从不同的表单和控制器创建设计用户 - Ruby on Rails

时间:2016-05-20 06:37:56

标签: ruby-on-rails model-view-controller devise

我们有两个模型,一个是“设计用户”和一个“影响者”。影响者是用户,因此它必须具有用户(从db角度来看)。用户可以是多个其他事物。因此,我们希望能够在不成为影响者的情况下注册用户,并且当他们想要注册为影响者时我们想要注册用户。

我有一个这样的表格:

influencers/new.html.erb

<%= form_for @influencer do |i| %>
  <%= i.fields_for(resource, as: resource_name, url: registration_path(resource_name)) do |u| %>
    <div id="registration_fields">
      <%= render 'devise/registrations/registration_fields', f: u %>
    </div>
  <% end %>

<div class='field'>
  <%= i.label :twitter_handle %><br/>
  <%= i.text_field :twitter_handle %>
</div>

<div class='field'>
  <%= i.label :short_bio %><br/>
  <%= i.text_area :short_bio %>
</div>
  

/views/devise/registrations/_registration_fields

<%= devise_error_messages! %>

<div class="field">
  <%= f.label :first_name %> <br />
  <%= f.text_field :first_name %>
</div>

<div class="field">
  <%= f.label :last_name %> <br />
  <%= f.text_field :last_name %>
</div>

<div class="field">
  <%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
  <%= f.label :password %>
  <% if @minimum_password_length %>
  <em>(<%= @minimum_password_length %> characters minimum)</em>
  <% end %><br />
  <%= f.password_field :password, autocomplete: "off" %>
</div>

<div class="field">
  <%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>

我们修改了ApplicationHelper和'new'方法,以便它可以毫无问题地呈现此Devise表单。不幸的是,我们仍然坚持如何为InfluencersController正确制作'create'方法。

这是我们收到的哈希:

Parameters: {..., "influencer"=>{"user"=>{"first_name"=>"buddy", "last_name"=>"king", "email"=>"bdking@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "twitter_handle"=>"@bdking", "short_bio"=>"None"}, "commit"=>"Join as influencer"

基本上我们希望在处理影响者信息时设计用于处理用户信息。我们尝试从InfluencersController #create中调用Devise :: RegistrationsController.new.create方法。然而,这带来了它自己的困难(即使有多次黑客攻击我们遇到了不同的问题,例如,缺少'@response'或缺少'response.env'或缺少'devise.mappings')。

话虽如此,我们相信继承将允许我们在create函数中调用'super'。但是,我们不希望InfluencersController继承自Devise :: RegistrationsController,因为这个控制器绝不是真正的Devise控制器。

我们有什么方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我会使用usersroles的尝试和真实模式。

基本上,您的User类负责身份验证(身份),并且用户有许多Roles可用于授权(权限)。

class User < ActiveRecord::Base
  has_many :roles

  def has_role?(role)
    roles.where(name: role)
  end
end

class Role < ActiveRecord::Base
  belongs_to :user
  validates_uniqueness_of :name, scope: :user_id
end

所以&#34;影响者&#34;实际上只是一个附加了角色(名称:&#34;影响者&#34;)的用户。真正的强大功能和灵活性在于,从Web GUI实现授予/撤销角色变得微不足道。

而且你不必弄乱Devise / Warden如何处理身份验证以支持多个可能变得非常混乱的类。

最好的部分是Rolify gem使得设置真的很简单。

如果您需要设置一个特定的端点(influences/registrations)来注册&#34;影响者&#34;你可以简单地覆盖Devise控制器中的build_resource方法:

class InfluencerRegistrationsController < Devise::RegistrationsController

  def resource_class
    User
  end

  def build_resource
    super
    self.resource.roles.new(name: :influencer)
  end
end