Best_In_Place 具有嵌套属性的内联编辑
Best_In_Place inline edits with nested attributes
我目前正在尝试使用 best_in_place gem 以便在 HTML table 中进行内联编辑。我正在购物车的展示视图中展示购物车。在购物车的显示视图中,我可以添加 lineItems。创建 LineItem 时,还会创建一个带有 lineItem_id 的新 Available 记录,然后它会与其 lineitem 一起显示在购物车中。购物车和 LineItem tables 都来自外部数据库,因此,我不能添加列,所以这就是为什么我不能只向 LineItem 添加可用的布尔属性。
**cart.rb
class Cart << AR::Base
has many LineItems
end
**line_item.rb
class LineItems <<AR::Base
belongs_to Cart
has_one :available
accepts_nested_attributes_for :available
end
**available.rb
class Available<<AR::Base
belongs_to LineItems
end
**views/cart/show.html.erb
@cart.lineitems.each do |line_items|
<td><%= line_item.price %></td>
<td><%=line_item.name %></td>
<td><%= best_in_place line_item.available.boolean, :boolean, :path => line_items_path, :type => type: :checkbox, collection: %w[No Yes] %></td>
end
我希望能够使用 best_in_place 在购物车显示视图中的 html table 中编辑 line_item.available.boolean,但我没有任何运气.. 任何帮助都会很棒! =] 我在阅读后知道使用嵌套属性是不可能的,但是如果我能以某种方式摆脱可用模型并在节目 table 中有一个字段,我可以将其编辑为 line_item查看 lineItem 是否可用,这也很好。我愿意接受任何想法!
首先,我们需要修复您的代码中的一些语法问题:
@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
现在,答案:
正如我在 this Github issue 中解释的那样,您需要传递一个 param
选项和一个 url
选项(以前是 path
但在 v3 中已弃用。 0.0) 至 best_in_place.
url
选项
默认url是best_in_place第一个参数的更新动作。由于您的代码以 best_in_place line_item.available
开头,因此默认为 url_for(line_item.available.id)
。但是,您希望它修补 LineItemsController 的更新操作,即 url_for(line_item)
param
选项
默认情况下,param 选项假定您正在 PATCH'ing 到 AvailablesController,因此这里是 Rails 约定需要的参数,以便将 available.boolean 更新为值“1”:
{"available"=>{"boolean"=>"1"}}
Available 的 ID 已经在 URL 中,因此您需要传递的唯一额外参数是 boolean
.
的新值
但是,在您的情况下,您正在 PATCH'ing 到 LineItemsController 并且可用模型接受嵌套属性。这需要两个调整:
LineItem 的 ID 已经在 URL 中,但 Available 的 ID 不在。我们在这里有两个选择:要么将 Available 的 ID 放入参数选项中,要么通过在模型中将 update_only: true
传递给 accepts_nested_attributes
来使 ID 变得不必要。根据您的用例,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
选项。
# 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]"
我目前正在尝试使用 best_in_place gem 以便在 HTML table 中进行内联编辑。我正在购物车的展示视图中展示购物车。在购物车的显示视图中,我可以添加 lineItems。创建 LineItem 时,还会创建一个带有 lineItem_id 的新 Available 记录,然后它会与其 lineitem 一起显示在购物车中。购物车和 LineItem tables 都来自外部数据库,因此,我不能添加列,所以这就是为什么我不能只向 LineItem 添加可用的布尔属性。
**cart.rb
class Cart << AR::Base
has many LineItems
end
**line_item.rb
class LineItems <<AR::Base
belongs_to Cart
has_one :available
accepts_nested_attributes_for :available
end
**available.rb
class Available<<AR::Base
belongs_to LineItems
end
**views/cart/show.html.erb
@cart.lineitems.each do |line_items|
<td><%= line_item.price %></td>
<td><%=line_item.name %></td>
<td><%= best_in_place line_item.available.boolean, :boolean, :path => line_items_path, :type => type: :checkbox, collection: %w[No Yes] %></td>
end
我希望能够使用 best_in_place 在购物车显示视图中的 html table 中编辑 line_item.available.boolean,但我没有任何运气.. 任何帮助都会很棒! =] 我在阅读后知道使用嵌套属性是不可能的,但是如果我能以某种方式摆脱可用模型并在节目 table 中有一个字段,我可以将其编辑为 line_item查看 lineItem 是否可用,这也很好。我愿意接受任何想法!
首先,我们需要修复您的代码中的一些语法问题:
@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
现在,答案:
正如我在 this Github issue 中解释的那样,您需要传递一个 param
选项和一个 url
选项(以前是 path
但在 v3 中已弃用。 0.0) 至 best_in_place.
url
选项
默认url是best_in_place第一个参数的更新动作。由于您的代码以 best_in_place line_item.available
开头,因此默认为 url_for(line_item.available.id)
。但是,您希望它修补 LineItemsController 的更新操作,即 url_for(line_item)
param
选项
默认情况下,param 选项假定您正在 PATCH'ing 到 AvailablesController,因此这里是 Rails 约定需要的参数,以便将 available.boolean 更新为值“1”:
{"available"=>{"boolean"=>"1"}}
Available 的 ID 已经在 URL 中,因此您需要传递的唯一额外参数是 boolean
.
但是,在您的情况下,您正在 PATCH'ing 到 LineItemsController 并且可用模型接受嵌套属性。这需要两个调整:
LineItem 的 ID 已经在 URL 中,但 Available 的 ID 不在。我们在这里有两个选择:要么将 Available 的 ID 放入参数选项中,要么通过在模型中将
update_only: true
传递给accepts_nested_attributes
来使 ID 变得不必要。根据您的用例,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
选项。
# 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]"