2

嘿,不是 Rails 菜鸟,但这让我很难过。With 在 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 字符串。然后它在酒单中插入一个新的关联。这将是昂贵的,但如果被破坏的关联行没有元数据,例如单个酒吧每杯和每瓶的价格,那很好。

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

谢谢。

4

1 回答 1

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”——它获取相关联的葡萄酒 ID 列表并将它们转换为表单可以使用的字符串。下一个方法是“setter”,它接受一个以逗号分隔的 id 字符串,并将其分解为wine_ids=接受的数组。

您可能还对我的文章Dynamic Form Elements in Rails感兴趣,它概述了 rails 表单输入如何不限于数据库记录中的属性。可以使用任何一对访问器方法。

于 2010-12-13T06:04:43.043 回答