簡體   English   中英

設計和多個“用戶”模型

[英]devise and multiple “user” models

我正在使用rails 3.2和設計2.0,我對Rails很新。

要求

我想實現以下目標:

  • 具有2個或更多“用戶”模型,例如。 會員,客戶,管理員
  • 所有型號共享一些必填字段(例如電子郵件和密碼)
  • 每個模型可能有一些獨特的領域(例如,僅限客戶的公司)
  • 某些字段可能是共享的但沒有相同的驗證(例如,客戶需要名稱,但會員可選)
  • 注冊過程中必須填寫所有字段,因此表單不同
  • 登錄表單應該是唯一的

可能的解決方案

我用Google搜索並搜索了StackOverflow很長一段時間,但對我來說似乎沒什么問題(我是一個Java人,對不起:)現在我很困惑。 出現了兩個解決方案:

單一設計用戶

這是最常見的答案。 只需創建默認設備用戶並在會員 - >用戶和客戶 - >用戶之間創建關系。 我關注的是如何為每個模型實現自定義注冊流程? 我嘗試了不同的東西,但一切都結束了!

多個設計用戶

這解決了自定義注冊過程,對我來說似乎是正確的,但唯一的登錄表單是一個阻止程序。 我在SO( Devise - 從兩個模型登錄 )上找到了答案,建議覆蓋Devise :: Models :: Authenticatable.find_for_authentication(條件)。 這似乎很復雜(?),因為我是鐵桿新手,我想知道這是否有效?

謝謝你的建議!

歡迎加入Java guy =),我希望你會喜歡Rails世界。 簡單地說,要解決您的問題,您有兩個解決方案:

  1. 為每個用戶在數據庫和相應的模型中創建一個表。
  2. 在數據庫中創建單個表,並為每個用戶類型創建一個模型。 這稱為單表繼承(STI)。

哪一個選擇? 它取決於角色的共同屬性。 如果它們幾乎是常見的(例如,所有都有名稱,電子郵件,移動設備......)並且一些屬性不同,我強烈推薦STI解決方案。

如何做STI? 1.只需使用命令rails generate devise User創建設計用戶模型和表rails generate devise User 2.使用遷移將名為type with string datatype的列添加到數據庫中的用戶表。 3.為每個用戶類型創建一個模型(例如rails g model admin )4。使Admin類繼承自用戶模型

class Admin < User
end

那就是你做完了=)...... Yupeee

要創建管理員,請運行命令Admin.create(...) ,其中點是管理員屬性,例如電子郵件,名稱,...

我認為這個問題對你也有幫助

在嘗試各種各樣的方法之后,我和你一樣,我使用單一的User模型,這將屬於多態角色。 這似乎是實現單一登錄的最簡單方法。

用戶模型將包含特定於登錄的信息。

角色模型將存儲特定於每個角色的字段,以及特定於該角色的其他關聯。

將通過各個控制器為每個用戶類型(角色)自定義新注冊,然后為用戶構建嵌套屬性。

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; 因為要求是用戶只能屬於一種類型的角色。

我找到了一條路可走,到目前為止我對它很滿意。 我會在這里為其他人描述。

我選擇了單一的“用戶”課程。 我的問題是為每個偽模型實現自定義注冊過程。

型號/ 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-formshttp://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

那有什么不對? 只需運行rails g devise:views [model_name] ,自定義每個注冊表單,並在config/initializer/devise.rb config.scoped_views = true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM