我目前正在尝试使用best_in_place gem,以便在HTML表中进行内联编辑。我在购物车的展示 View 中显示购物车。在购物车的显示 View 中,我可以添加lineItems。创建LineItem时,还将使用lineItem_id创建新的Available记录,然后将其与lineitem一起显示在购物车中。 Cart表和LineItem表均来自外部数据库,因此,我无法向其添加列,因此,我不能仅向LineItem添加可用的 bool 属性。

**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在购物车展示 View 上的html表中编辑line_item.available.boolean,但是我没有任何运气。任何帮助都将是惊人的! =]阅读后,我知道无法使用嵌套属性,但是如果我能以某种方式摆脱可用的模型,并在show表中有一个字段,可以编辑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选项假定您正在对AvailablesController进行PATCH,因此,这是Rails约定为了将available.boolean更新为值“1”所需的参数:
{"available"=>{"boolean"=>"1"}}

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

但是,在您的情况下,您要对LineItemsController进行修补,并且可用的模型接受嵌套的属性。这需要两项调整:
  • LineItem的ID已经在URL中,而Available ID则不在。我们在这里有两个选择:将Available的ID放入param选项中,或者通过将update_only: true传递给模型中的accepts_nested_attributes来使ID不必要。 update_only方法可能不适用于您,具体取决于您的用例,但是我发现它在大多数时候是最简单的方法,并且免费添加了一层额外的安全性。
  • bool 选项需要正确嵌套,即:
    line_items[available_attributes][boolean]
    

    这样,当它到达服务器时,参数将是:
    {"line_item"=>{"available_attributes"=>{"id"=>"99","boolean"=>"1"}}}
    # "99" is just an example of line_item.available.id
    

    请注意,您将需要在 Controller 中允许这些属性,即:
    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]"
    

    10-07 12:52