具有嵌套属性的Best_In_Place内联编辑

我目前正在尝试使用best_in_place gem来在HTML表格中进行内联编辑。 我在购物车的展示视图中显示了一个购物车。 在购物车的展示视图中,我可以添加lineItems。 创建LineItem时,还会使用lineItem_id创建新的可用记录,然后在购物车中显示其lineitem。 Cart和LineItem表都来自外部数据库,因此我无法添加列,这就是为什么我不能只为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|    line_items_path, :type => type: :checkbox, collection: %w[No Yes] %> end 

我希望能够使用best_in_place编辑html表中的line_item.available.boolean,该表位于购物车展示视图中,但我没有任何运气..任何帮助都会令人惊叹! =]我知道在阅读之后,使用嵌套属性是不可能的,但是如果我能以某种方式摆脱可用模型并在show table中有一个字段,我可以为line_item编辑以查看lineItem是否可用那也很棒。 我对任何想法持开放态度!

首先,我们需要修复代码中的一些语法问题:

 @cart.lineitems.each do |line_item| # changed "line_items" to "line_item" <%= line_item.price %> <%=line_item.name %> <%= best_in_place line_item.available, :boolean, :path => line_items_path, type: :checkbox, collection: %w[No Yes] %> # changed "line_item.available.boolean" to "line_item.available" and ":type => type: :checkbox" to "type: :checkbox" end 

现在,答案是:

正如我在这个Github问题中解释的那样,你需要传递一个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) 。 但是,您希望它PATCH LineItemsController的更新操作,即url_for(line_item)

param选项

默认情况下,param选项假设您正在对可用控件进行PATCH操作,因此以下是Rails约定所需的参数,以便将available.boolean更新为值“1”:

 {"available"=>{"boolean"=>"1"}} 

可用的ID已经在URL中,因此您需要传递的唯一额外参数是boolean的新值。

但是,在您的情况下,您正在对LineItemsController进行PATCH,并且可用模型接受嵌套属性。 这需要两个调整:

  1. LineItem的ID已在URL中,但Available的ID不在。 我们在这里有两个选择:将Available的ID放入param选项,或者通过将update_only: true传递给模型中的accepts_nested_attributes来使ID不必要。 根据您的使用情况, update_only方法可能对您不起作用,但我发现它是绝大多数时候最简单的方法,并且免费添加了额外的安全层。

  2. 布尔选项需要正确嵌套,即:

     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]"