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


Я использую rails 3.2 и devise 2.0, и я совсем новичок в Rails.

требования

Я хотел бы получить следующее:

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

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

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

один пользователь devise

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

несколько пользователей devise

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

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

4 72

4 ответа:

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

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

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

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

class Admin < User
end

вот и все, что вы сделали =)... Yupeee

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

Я думаю, что это вопрос может помочь вам слишком

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

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

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

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

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

views / members / new.формат html.Эрб

<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; так как требование заключается в том, что пользователь может принадлежать только к одному типу роли.

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

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

модели/пользователя.РБ:

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 иметь два пути регистрации с помощью переопределить контроллер:

в config/маршруты.РБ:

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.РБ:

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

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

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