2016-05-20 64 views
1

我們有兩個模型,'設計用戶'和'影響者'。一個影響者是一個用戶,因此它必須有一個用戶(從數據庫的角度來看)。用戶可以是多種其他的東西。因此,我們希望能夠在不成爲影響者的情況下注冊用戶,並且我們希望在用戶想要註冊爲影響者時註冊用戶。從不同的窗體和控制器創建設計用戶 - Ruby on Rails

我有一個表格,像這樣:

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和 '新' 的方法,以便它可以使這種設計形式沒有問題。不幸的是,我們堅持如何正確地爲我們的InfluencersController創建'創建'方法。

這是我們收到的哈希:

Parameters: {..., "influencer"=>{"user"=>{"first_name"=>"buddy", "last_name"=>"king", "email"=>"[email protected]", "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')。

就這樣說,我們認爲繼承將允許我們在創建函數中調用'超級'。然而,我們不想讓InfluencersController繼承自Devise :: RegistrationsController,因爲這個控制器並不是真正的Devise控制器。

有什麼辦法可以解決這個問題嗎?

回答

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 

因此,一個「影響者」僅僅是一個與角色(名稱:「影響者」)的用戶連接到它。真正的力量和靈活性在於,通過Web GUI實現授予/撤銷角色變得微不足道。

而且,您不必亂用Devise/Warden如何處理身份驗證以支持多個可能變得非常混亂的類。

最好的部分是,Rolify gem使它設置真的很微不足道。

如果您需要設置一個特定端點(influences/registrations)註冊「影響力」,你可以簡單地覆蓋在設計控制器build_resource方法:

class InfluencerRegistrationsController < Devise::RegistrationsController 

    def resource_class 
    User 
    end 

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

如果你絕對必須的,你可以使用STI或MTI。但就複雜性和性能而言,這些缺點相當巨大。 – max

+0

什麼是STI或MTI?你說得對,我們正在使用用戶角色,其中一個角色是影響者。但是,由於影響者擁有額外的數據成員,我們將它們作爲自己的表格。我問是否有方法讓InfluencersController註冊一個用戶,而不從它繼承Devise :: RegistrationsController。 –

+0

單表繼承和多表繼承。是的,你可以從頭開始創建一個註冊用戶的控制器 - 它與任何其他CRUD控制器都沒什麼不同,除了你調用'sign_in @ user'來讓Warden在重定向之前將會話ID存儲在會話中。 – max

相關問題