我正在使用rails 3.2和Desive 2.0,我对rails还很陌生.

Requirements

我希望实现以下目标:

  • 拥有两个或两个以上的"用户"模型,如会员、客户、管理员
  • 所有型号共享一些必填字段(例如邮箱和密码)
  • 每个型号可能有一些独特的字段(例如,仅限客户使用的公司)
  • 某些字段可能是共享的,但没有相同的验证(例如,客户需要名称,但成员可以 Select 名称)
  • 所有字段都必须在注册过程中填写,因此表格不同
  • 登录表单应该是唯一的

Possible solutions

我在谷歌上搜索StackOverflow有很长一段时间了,但在我看来没有什么是对的(我是一个Java爱好者,抱歉:),现在我很困惑.出现了两种解决方案:

单一设计用户

That's the most frequent answer. Just create the default devise User and create relations between Member-->User and Customer-->User. My concern here is how can I achieve a customized registration process for each model? I tried different things but all ended as a mess!

多用户设计

这解决了自定义注册过程,对我来说似乎是正确的,但唯一的登录表单是一个拦截器.我在SO(Devise - login from two model)上找到了一个答案,建议覆盖Desive::Models::Authenticatable.查找\u以进行\u身份验证(条件).

谢谢你的建议!

推荐答案

我找到了一条路要走,到目前为止我很满意.我将在这里为其他人描述它.

我 Select 了单一"用户"类.我的问题是 for each 伪模型实现定制的注册过程.

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

然后,我调整了http://railscasts.com/episodes/217-multistep-formshttp://pastie.org/1084054,使其具有两条覆盖控制器的注册路径:

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:

我创建了一个向导类,它知道每个步骤要验证的字段

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_member.rb根据向导步骤包括一部分:

Ruby-on-rails相关问答推荐

ruby on rails:错误未知关键字::当使用google-cloud-storage下载文件时,soft_deleted

GO AES GCM加密在解密时出错&S

DateTime的最小数据提交格式

Web控制台不会出现在例外页面Rails 7.1.1上

关于关联 has_many 的多级/三重嵌套形式

如何从数组中提取值

Rails 7,Hotwire 动态表单,更新值不起作用

如何使用失败try 次数使设计可锁定

Rails - 使用 %W

如何在where子句中组合两个条件?

Rails 5:无法从参数中检索哈希值

Rails:如何在表单的必填字段上禁用星号?

Rspec 与 TestUnit

如何将变量 link_to 定义为外部 URL

格式化日期对象以显示人类可读的日期

确认后如何进行设计重定向

Ruby 更新后:测试失败,assets资源 未声明为在生产中预编译

Date.current 和 Date.today 有什么区别?

如何在不触及 updated_at 属性的情况下更新单个属性?

如何创建一个 ruby​​ Hello 世界?