首先,我们需要修复代码中的一些语法问题:
@cart.lineitems.each do |line_item| # changed "line_items" to "line_item"
<td><%= line_item.price %></td>
<td><%=line_item.name %></td>
<td><%= best_in_place line_item.available, :boolean, :path => line_items_path, type: :checkbox, collection: %w[No Yes] %></td> # changed "line_item.available.boolean" to "line_item.available" and ":type => type: :checkbox" to "type: :checkbox"
end
现在,答案是:
正如我所解释的这个 Github 问题 https://github.com/bernat/best_in_place/issues/51#issuecomment-99951342,你需要通过一个param
选项和一个url
选项(以前是path
但这在 v3.0.0 中已被弃用)为 best_in_place。
The url
option
默认 url 是 best_in_place 第一个参数的更新操作。由于您的代码开头为best_in_place line_item.available
,这将默认为url_for(line_item.available.id)
。但是,您希望它修补 LineItemsController 的更新操作,即url_for(line_item)
The param
option
默认情况下,param 选项假定您正在 PATCH'ing 到 availablescontroller,因此以下是 Rails 约定所需的参数,以便将 available.boolean 更新为值“1”:
{"available"=>{"boolean"=>"1"}}
可用的 ID 已在 URL 中,因此您需要传递的唯一额外参数是新值boolean
.
然而,在您的情况下,您正在修补 LineItemsController 并且可用模型接受嵌套属性。这需要两个调整:
LineItem 的 ID 已在 URL 中,但 available 的 ID 不在 URL 中。这里我们有两个选择:要么将Available的ID放入param选项中,要么通过传递使ID变得不必要update_only: true
to accepts_nested_attributes
在模型中。这update_only
根据您的用例,该方法可能不适合您,但我发现它在绝大多数情况下是最简单的方法,并且免费添加了额外的安全层。
-
布尔选项需要正确嵌套,即:
line_items[available_attributes][boolean]
这样,当它到达服务器时,参数将是:
{"line_item"=>{"available_attributes"=>{"id"=>"99","boolean"=>"1"}}}
# "99" is just an example of line_item.available.id
请注意,您需要在控制器中允许这些属性,即:
line_item.update(params.require(:line_item).permit(
available_attributes: [:id, :boolean]))
# You can remove `:id` if you are using the `update_only` option
将它们放在一起,这是您的 best_in_place 方法:
best_in_place line_item.available, :boolean,
type: :checkbox,
url: line_item_path(line_item.id),
param: "line_item[available_attributes][id]=#{line_item.available.id}&line_item[available_attributes]"
但是,如果可能的话,请使用update_only
option.
# line_item.rb
accepts_nested_attributes_for :available, update_only: true
看看现在变得多么简单:
best_in_place line_item.available, :boolean,
type: :checkbox,
url: line_item_path(line_item.id),
# Note: `url: line_item` might also work.
# If someone can confirm this in a comment, I can update this answer
param: "line_item[available_attributes]"