2010-11-02 57 views
1

我有2種型號,CategoryLineItemTypes創建或刪除協會與accepts_nested_attributes_for

已經有很多現有的都有,現在是他們相關的要求。每個類別都有很多LineItemTypes。

我已經Category

添加accepts_nested_attributes_for :line_item_types我在窗體上使用hidden_field創建的現有相關LineItemTypes列表嘗試:如果我添加項目到該列表

- form_for @category do |form| 
    %ul#categorised 
    - form.fields_for :line_item_types do |line_item_types| 
     -categorised.each do |l| 
     %li 
      =l.description 
      =line_item_types.hidden_field :category_id 

    =form.submit 

,我出現錯誤,指出無法找到該類別的LineItemType。我以爲accepts_nested_attributes_for想補充的關係,如果它不存在。或者只是爲了「創造」新記錄和修改現有關係,而不是創建新的關係。

a.update_attributes({:line_item_types_attributes => [{:id => 2767}, {:id => LineItemType.find(2).id}]}) 
ActiveRecord::RecordNotFound: Couldn't find LineItemType with ID=2 for Category with ID=1 

任何想法,而不必寫東西來遍歷結果形式參數並創建關聯?或者更簡單的方法來實現這一點?

回答

2

我得出結論,accept_nested_attributes_for作品有點像url_for ...身份證的存在使得它假定關係存在。渲染accepts_nested_attributes_for不適合我想做的事情。

我過濾器之前解決此工作了:

def find_line_item_types 
    params[:category][:line_item_types] = LineItemType.find(params[:category][:line_item_types].collect { |a| a[0].to_i }) if params[:category] and params[:category][:line_item_types] 
end 
0

沒有,你應該能夠不用在line_item_types屬性指定CATEGORY_ID創建從類別實例line_item_types!

你應該檢查你的has_many和belongs_to聲明中是否有inverse_of選項。

# in Category 
has_many :line_item_types, :inverse_of => :category 

# In LineItemType 
belongs_to :category, :inverse_of => :line_item_types 

告訴我,如果有幫助。

+0

對不起,仍然有同樣的錯誤。我可以創建在該類別NEW line_item_types但我不能與現有的類別現有line_item_types關聯... – stuartc 2010-11-02 15:02:16

0

嗯,我有同樣的問題,所以我搜索到源和猴子修補accepts_nested_attributes_for允許這種行爲......

https://gist.github.com/2223565

看起來很多,但實際上我只是修改幾行:

module ActiveRecord::NestedAttributes::ClassMethods 
    def accepts_nested_attributes_for(*attr_names) 
    # ... 
    #options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only) 
    options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only, :allow_existing) 
    # ... 
    end 
end 

And ...

module ActiveRecord::NestedAttributes 
    def assign_nested_attributes_for_collection_association(association_name, attributes_collection, assignment_opts = {}) 
    # ... 
    #existing_records = if association.loaded? 
    # association.target 
    #else 
    # attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact 
    # attribute_ids.empty? ? [] : association.scoped.where(association.klass.primary_key => attribute_ids) 
    #end 

    existing_records = if options[:allow_existing] or not association.loaded? 
     attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact 
     scope = options[:allow_existing] ? association.target_scope : association.scoped 
     scope.where(association.klass.primary_key => attribute_ids) 
    else 
     association.target 
    end 
    # ... 
    end 
end