Разработать и несколько "пользовательских" моделей

Я использую рельсы 3.2 и разрабатываю 2.0, и я совершенно новый для Rails.

Требования

Я хотел бы сделать следующее:

  • имеют 2 или более "пользовательских" моделей, например. Пользователь, Клиент, Администратор
  • все модели имеют некоторые обязательные поля (например, адрес электронной почты и пароль).
  • каждая модель может иметь несколько уникальных полей (например, только для клиентов)
  • некоторые поля могут быть разделены, но не имеют одинаковой проверки (например, имя требуется для Клиента, но необязательно для участника).
  • все поля должны быть заполнены во время процесса регистрации, поэтому формы различаются
  • форма входа должна быть уникальной.

Возможные решения

Я долго искал и искал StackOverflow, но мне ничего не кажется правильным (я парень Java, извините:) и теперь я совершенно смущен. Появились два решения:

Пользователь с одним дизайном

Это самый частый ответ. Просто создайте созданный по умолчанию пользователь и создайте отношения между Member → User и Customer → User. Меня беспокоит, как я могу добиться индивидуального процесса регистрации для каждой модели? Я пробовал разные вещи, но все закончилось как беспорядок!

Несколько разработчиков

Это решает процесс пользовательской регистрации и кажется мне правильным, но уникальная форма входа - блокиратор. Я нашел ответ на SO (Devise - логин от двух моделей), который предлагает переопределить Devise:: Models:: Authenticatable.find_for_authentication (условия). Это кажется сложным (?), И поскольку я новичок в рельсах, я хотел бы знать, может ли это работать?

Спасибо за ваш совет!

Ответ 1

Я нашел способ пойти, и я доволен этим до сих пор. Я опишу его здесь для других.

Я пошел с единственным "пользовательским" классом. Моя проблема заключалась в том, чтобы создать индивидуальный процесс регистрации для каждой псевдомодели.

модель /user.rb:

class User < ActiveRecord::Base
  devise :confirmable,
       :database_authenticatable,
       :lockable,
       :recoverable,
       :registerable,
       :rememberable,
       :timeoutable,
       :trackable,
       :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :role

  as_enum :role, [:administrator, :client, :member]
  validates_as_enum :role
  ## Rails 4+ for the above two lines
  # enum role: [:administrator, :client, :member]

end

Затем я адаптировал http://railscasts.com/episodes/217-multistep-forms и http://pastie.org/1084054 иметь два пути регистрации с переопределенным контроллером:

конфиг /routes.rb:

get  'users/sign_up'   => 'users/registrations#new',        :as => 'new_user_registration'

get  'clients/sign_up' => 'users/registrations#new_client', :as => 'new_client_registration'
post 'clients/sign_up' => 'users/registrations#create',     :as => 'client_registration'

get  'members/sign_up' => 'users/registrations#new_member', :as => 'new_member_registration'
post 'members/sign_up' => 'users/registrations#create',     :as => 'member_registration'

Контроллеры/пользователи/registrations_controller.rb:

Я создал класс мастера, который знает поля для проверки на каждом шаге

class Users::RegistrationsController < Devise::RegistrationsController

    # GET /resource/sign_up
    def new
        session[:user] ||= { }
        @user = build_resource(session[:user])
        @wizard = ClientRegistrationWizard.new(current_step)

        respond_with @user
    end

    # GET /clients/sign_up
    def new_client
        session[:user] ||= { }
        session[:user]['role'] = :client
        @user = build_resource(session[:user])
        @wizard = ClientRegistrationWizard.new(current_step)

        render 'new_client'
    end

    # GET /members/sign_up
    def new_member
      # same
    end

    # POST /clients/sign_up
    # POST /members/sign_up
    def create
        session[:user].deep_merge!(params[:user]) if params[:user]
        @user = build_resource(session[:user])
        @wizard = ClientRegistrationWizard.new(current_step)

        if params[:previous_button]
            @wizard.previous
        elsif @user.valid?(@wizard)
            if @wizard.last_step?
                @user.save if @user.valid?
            else
                @wizard.next
            end
        end

        session[:registration_current_step] = @wizard.current_step

        if @user.new_record?
            clean_up_passwords @user
            render 'new_client'
        else
            #session[:registration_current_step] = nil
            session[:user_params] = nil

            if @user.active_for_authentication?
                set_flash_message :notice, :signed_up if is_navigational_format?
                sign_in(:user, @user)
                respond_with @user, :location => after_sign_up_path_for(@user)
            else
                set_flash_message :notice, :"signed_up_but_#{@user.inactive_message}" if is_navigational_format?
                expire_session_data_after_sign_in!
                respond_with @user, :location => after_inactive_sign_up_path_for(@user)
            end
        end

    end

    private

    def current_step
        if params[:wizard] && params[:wizard][:current_step]
            return params[:wizard][:current_step]
        end
        return session[:registration_current_step]
    end

end

и мои представления:

  • new.rb
  • new_client.rb, включая частичный шаг мастера:
    • _new_client_1.rb
    • _new_client_2.rb
  • new_member.rb, включая частичный шаг мастера:
    • _new_member_1.rb
    • _new_member_2.rb

Ответ 2

Добро пожаловать на борт Java guy =), надеюсь, вам понравится мир Rails. Просто, чтобы решить вашу проблему, у вас есть 2 решения:

  • Для каждого пользователя создайте таблицу в базе данных и соответствующей модели.
  • Создайте единую таблицу в базе данных и для каждого типа пользователя создайте модель. Это называется наложением одиночной таблицы (STI).

Какой из них выбрать? Это зависит от общих атрибутов ролей. Если они почти повсеместны (например, все имеют имя, адрес электронной почты, мобильный,...), и несколько атрибутов разные, я настоятельно рекомендую решение STI.

Как сделать ИППП? 1. Просто создайте модель и таблицу пользователя для разработки с помощью команды rails generate devise User 2. Добавьте столбец с именем type со строковым типом данных в пользовательскую таблицу в базе данных с помощью переноса. 3. Для каждого типа пользователя создайте модель (например, rails g model admin) 4. Наследовать класс Admin от модели пользователя.

class Admin < User
end

Что это вы сделали =)... Yupeee

Чтобы создать администратор, запустите команду Admin.create(...), где точки - это атрибуты администратора, например, адрес электронной почты, имя,...

Я думаю, что question может вам помочь.

Ответ 3

Я в такой же обуви, как и вы, пробовав всевозможные подходы, я пошел с одной моделью пользователя, которая будет принадлежать полиморфным ролям. Это похоже на самый простой способ добиться единого входа.

Модель User будет содержать информацию, специфичную только для входа в систему.

В модели Role будут храниться поля, специфичные для каждой роли, а также другие ассоциации, специфичные для этой роли.

Новые регистрации будут настраиваться для каждого типа пользователя (ролей) через отдельные контроллеры, а затем для встраивания вложенных атрибутов для пользователя.

class User < ActiveRecord::Base
    #... devise code ...
    belongs_to :role, :polymorphic => true
end

class Member < ActiveRecord::Base
    attr_accessible :name, :tel, :city  #etc etc....
    attr_accessible :user_attributes #this is needed for nested attributes assignment

    #model specific associations like  
    has_many :resumes

    has_one :user, :as => :role, dependent: :destroy
    accepts_nested_attributes_for :user
end 

Маршруты - просто обычные материалы для модели участника.

resources :members
#maybe make a new path for New signups, but for now its new_member_path

Контроллер - вы должны build_user для вложенных атрибутов

#controllers/members_controller.rb
def new
    @member = Member.new
    @member.build_user
end

def create
    #... standard controller stuff
end

просмотров/Участники/new.html.erb

<h2>Sign up for new members!</h2>
<%= simple_form_for @member do |f| %>

    # user fields
    <%= f.fields_for :user do |u| %>
      <%= u.input :email, :required => true, :autofocus => true %>
      <%= u.input :password, :required => true %>
      <%= u.input :password_confirmation, :required => true %>
    <% end %>

    # member fields
    <%= f.input :name %>
    <%= f.input :tel %>
    <%= f.input :city %>

    <%= f.button :submit, "Sign up" %>
<% end %>

Я хотел бы указать, что НИКОГДА НЕОБХОДИМОСЬ для создания nested_form gem; поскольку требование состоит в том, что Пользователь может принадлежать только одному типу Роли.

Ответ 4

Итак, что случилось? Просто запустите rails g devise:views [model_name], настройте каждую регистрационную форму и в config/initializer/devise.rb просто поставьте config.scoped_views = true.