devise和多个“用户”模型

我使用rails 3.2和devise2.0,我很新的Rails。

要求

我想达到以下目的:

  • 有2个或更多的“用户”模型,例如。 会员,客户,pipe理员
  • 所有模型共享一些必填字段(例如电子邮件和密码)
  • 每个模型可能有一些独特的领域(例如,仅限于客户的公司)
  • 一些字段可能会被共享,但是不具有相同的validation(例如,客户需要名称,但是会员可选)
  • 在注册过程中必须填写所有的字段,所以表格是不同的
  • login表单应该是唯一的

可能的解决scheme

我search了很长一段时间searchStackOverflow,但没有什么似乎对我来说(我是一个Java的人,对不起:)现在我很困惑。 两个解决scheme来了:

单个devise用户

这是最常见的答案。 只需创build默认的devise用户,并在成员 – >用户和客户 – >用户之间build立关系。 我关心的是如何为每个模型实现定制的注册过程? 我尝试了不同的东西,但都是一塌糊涂!

多个devise用户

这解决了自定义注册过程,似乎对我来说,但唯一的login表单是一个阻碍。 我find了一个答案( devise – 从两个模型login ),这build议覆盖devise::模型:: Authenticatable.find_for_authentication(条件)。 这似乎很复杂(?),因为我是新来的铁轨,我想知道这是否可以工作?

谢谢你的build议!

欢迎登上Java的家伙=),我希望你会喜欢Rails的世界。 简而言之,要解决您的问题,您有两个解决scheme:

  1. 为每个用户在数据库和相应的模型中创build一个表。
  2. 在数据库中创build一个表,并为每个用户types创build一个模型。 这被称为单表inheritance(STI)。

哪一个select? 这取决于angular色的共同属性。 如果它们几乎是常见的(例如,所有的都有名字,电子邮件,手机等),并且有一些属性是不同的,我强烈推荐STI解决scheme。

如何做STI? 1.使用命令rails generate devise User创builddevise用户模型和表2.使用迁移将名为type的string数据types添加到数据库中的用户表中。 3.为每个用户types创build一个模型(例如rails g model admin )4.使Admin类从用户模型inheritance

 class Admin < User end 

就是这样,你完成=)… Yupeee

要创build一个pipe理员运行命令Admin.create(...)其中的点是pipe理员的属性,例如电子邮件,名称,…

我想这个问题也可以帮到你

我和你一样,在尝试了各种方法之后,我使用了一个单一的用户模型,这个模型属于多态angular色。 这似乎是实现单一login的最简单方法。

用户模型将包含特定于login的信息。

angular色模型将存储特定于每个angular色的字段以及特定于该angular色的其他关联。

通过单独的控制器为每个用户types(angular色)定制新的注册,然后为用户构build嵌套属性。

 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没有必要达到, 因为要求是用户只能属于一种types的angular色。

我find了一条路,到目前为止我还是很满意的。 我会在这里描述给别人。

我去了单一的“用户”类。 我的问题是为每个伪模型实现一个自定义的注册过程。

型号/ 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有一个覆盖控制器的两个注册path:;

configuration/ 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:

我创build了一个向导类,它知道每个步骤要validation的字段

 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] ,自定义每个registry单,并在config/initializer/devise.rb放置config.scoped_views = true