has_many通过吹走协会关于群众协会的元数据

时间:2010-12-13 04:33:26

标签: ruby-on-rails associations has-many-through ruby-on-rails-3 mass-assignment

嘿 不是Rails noob,但这让我很难过。 在Rails中有许多通过关联。当我通过葡萄酒单协会(或通过)表格将葡萄酒大量分配到酒吧时。

class WineBarController

  def update

    @winebar = WineBar.find(params[:id])

    @winebar.wines = Wine.find(params[:wine_bar][:wine_ids].split(","))  // Mass assign wines.

    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 

  end

end

这将删除与该酒吧相关联的每个酒单行。然后它找到wine_ids中的所有葡萄酒,我们认为这是一个逗号分隔的葡萄酒ID。然后它将一个新的关联插入到winelist中。这将是昂贵的,但如果被破坏的关联行没有元数据,例如每个酒吧的每个玻璃和瓶子的价格,那就很好。

有没有办法让它不会吹走所有东西,只需对数组进行可枚举的比较,然后插入删除任何更改。我觉得这就是rails所做的事情,我只是错过了一些明显的东西。

感谢。

1 个答案:

答案 0 :(得分:2)

您的问题看起来与更新方法中的第一个语句一样 - 您正在创建新的酒吧记录,而不是加载现有记录并更新它。这就是为什么当你检查记录时,没有任何关系的显示。 Rails 足够聪明,不会删除/创建列表中的每条记录,所以不要担心。

如果您正在为表单使用标准导轨设置:

<% form_for @wine_bar do |f| %>

然后你可以这样调用你的更新:

class WineBarController
  def update
    @winebar = WineBar.find(params[:id])
    render (@winebar.update_attributes(params[:wine_bar]) ? :update_success : :update_failure) 
  end
end

您无需使用params[:wine_bar][:wine_ids]明确更新记录,因为当您使用params[:wine_bar]更新记录时,wine_ids已包含在其中。我希望这有帮助!

更新:您提到这不起作用,因为表单的设置方式,但您可以轻松修复它。在表单中,您需要将输入字段从wine_bar[wine_ids]重命名为wine_bar[wine_ids_string]。然后你只需要在你的模型中创建访问器,如下所示:

class WineBar < ActiveRecord::Base
  def wine_ids_string
    wines.map(&:id).join(',')
  end

  def wine_ids_string= id_string
    self.wine_ids = id_string.split(/,/)
  end
end

上面的第一个方法是“getter” - 它获取相关wine id的列表并将它们转换为表单可以使用的字符串。下一个方法是“setter”,它接受逗号分隔的id字符串,并将其分解为wine_ids=接受的数组。

您可能也对我的文章Dynamic Form Elements in Rails感兴趣,该文章概述了rails表单输入的方式不仅限于数据库记录中的属性。可以使用任何一对存取方法。