5

這一個真的讓我失望! :(Rails有許多通過多態複選框

我試圖做一個嵌套的模型形式爲我在裏面有一個複選框列表,其中多個商店,可以選中或取消選中通過模型人員配備來管理存儲的用戶模型。

class Staffing < ActiveRecord::Base 
    # Associations 
    belongs_to :user 
    belongs_to :staffable, :polymorphic => true 
    belongs_to :store,  :class_name => "Store", 
         :foreign_key => "staffable_id" 
end 

class User < ActiveRecord::Base 
    # Includes 
    acts_as_authentic 

    # Associations 
    has_many :staffings, :dependent => :destroy 
    has_many :stores, :through => :staffings 

    # Nested Attributes 
    accepts_nested_attributes_for :staffings, :allow_destroy => true 
end 

class Store < ActiveRecord::Base 
    # Associations 
    has_many :staffings, :as => :staffable, :dependent => :destroy 
    has_many :users, :through => :staffings 
end 


# Users Controller 
def create 
    @user = User.new(params[:user]) 
    flash.now[:notice] = "#{@user.name} was successfully created." if @user.save 
    respond_with @user 
end 


def update 
    @user = User.find(params[:id]) 
    params[:user][:store_ids] ||= [] 
    @user.update_attributes(params[:user]) 
    flash.now[:notice] = "#{@user.name} was successfully updated." 
    respond_with @user 
end 

對於其他staffable協會可以忽略不計的目的在眼前。這是一個類似的模型,我最終想要第一旁邊商店,但第一件事的管理,因爲我很爲難,因爲它是。

# User Form 
- for store in Store.all 
    %p 
    = check_box_tag "user[store_ids][]", store.id, @user.stores.include?(store) 
    = store.nickname 

發送我的PARAMS沿着這樣的:

{"utf8"=>"✓", 
"authenticity_token"=>"blub-blub-blub=", 
"user"=>{"login"=>"hey.buddy", 
"email"=>"[email protected]", 
"role"=>"admin", 
"hq"=>"1", 
"password"=>"[FILTERED]", 
"password_confirmation"=>"[FILTERED]", 
"store_ids"=>["3", 
"4"]}} 

然後錯誤!

Mysql2::Error: Column 'staffable_type' cannot be null: INSERT INTO `staffings` (`created_at`, `staffable_id`, `staffable_type`, `updated_at`, `user_id`) VALUES ('2010-11-17 00:30:24', 3, NULL, '2010-11-17 00:30:24', 102) 

我知道我必須打造出staffable_type爲「商店」,但我已經了一整天 - 有什麼訣竅?

我確實將staffable_type(和id)列設置爲:null => false,但這不可能是造成這種情況的原因,因爲無論如何都需要在控制器中將其清理出來。

爲什麼下面沒有在我創建行動工作:

@user.staffings.each do |s| 
    s.staffable_type = 'Store' 
end 

或:

@user.store_ids.each do |i| 
    s = @user.staffings.build 
    s.staffable_type = 'Store' 
    s.staffable_id = i 
end 

如果一直試圖與上述類似無濟於事很多東西。任何幫助將大規模讚賞。

謝謝你的時間!

回答

4

好吧我想出了這一個。我在這裏回答,所以我希望有一天能夠幫助別人,但問題是對許多通過並擁有和屬於許多社團的區別的基本監督。

如果您想處理Has Many Through中的複選框或多選列表,那麼關聯就不會爲您生成'_ids'方法,您需要爲自己編寫一個'_ids'方法。

看到了保羅·巴里的文章在這裏: http://paulbarry.com/articles/2007/10/24/has_many-through-checkboxes

多態的東西可能會很複雜,但如果你堅持真正的好,也許退一步,並確保它不是一些更基本的多數民衆贊成搞亂你up--爲我工作!

下面是保羅對如何處理這個,如果你正在處理一個多態博客修改的代碼有許多通過(基本上你只需要使用的屬性哈希,寫你的polymorphic_type屬性):

attr_accessor :store_ids 
after_save :update_stores 

#after_save callback to handle group_ids 
def update_stores 
    unless store_ids.nil? 
    self.staffings.each do |staffing| 
     staffing.destroy unless store_ids.include?(staffing.staffable_id.to_s) 
     store_ids.delete(staffing.staffable_id.to_s) 
    end 
    store_ids.each do |s| 
     self.staffings.create(attributes = {:staffable_id => s, :staffable_type => 'Store'}) unless s.blank? 
    end 
    reload 
    self.store_ids = nil 
    end 
end