devise and multiple “user” models

前端 未结 4 1674
[愿得一人]
[愿得一人] 2020-11-27 09:21

I\'m using rails 3.2 and devise 2.0 and I\'m quite new to Rails.

Requirements

I\'d like to achieve the following:

  • have 2 or more \"user\" mod
4条回答
  •  感动是毒
    2020-11-27 09:40

    I found a way to go and I'm quite happy with it so far. I'll describe it here for others.

    I went with the single "user" class. My problem was to achieve a customized registration process for each pseudo model.

    model/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
    

    Then I adapted http://railscasts.com/episodes/217-multistep-forms and http://pastie.org/1084054 to have two registration paths with an overridden controller:

    config/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'
    

    controllers/users/registrations_controller.rb:

    I created a wizard class which knows the fields to validate at each step

    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
    

    and my views are:

    • new.rb
    • new_client.rb including a partial according to the wizard step:
      • _new_client_1.rb
      • _new_client_2.rb
    • new_member.rb including a partial according to the wizard step:
      • _new_member_1.rb
      • _new_member_2.rb

提交回复
热议问题