2010-11-02 49 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