Rails使用has_many:through编辑连接表的其他字段

时间:2015-09-06 15:52:48

标签: ruby-on-rails nested-forms nested-attributes jointable

我遇到的问题与此几乎完全相同: Rails has_many :through saving additional fields

但是我无法弄清楚我的代码中缺少什么。基本结构如下:有产品,他们可能有其他服务(如清洁或锐化)。每项服务的基本价格相同,但产品可能有不同的系数。假设,产品1的基本价格可能会提高* 1.5,而产品2的基本价格可能会有所提高* 2.连接表被称为有点愚蠢 - 服务化,我无法找到一个不错的名称。

products_controller.rb:

def update
  @product.update!(product_params)
  redirect_to @product
end

def product_params
    params.require(:product).permit(
    :title, :description, :advertising_text, :fancy_quote, :hot, :hotpic, :product_size_ids, 
    { volume_ids: [] }, { color_ids: [] }, { addservice_ids: [] }, :category_id, :subcategory_id, 
    options_attributes: [:size, :weight, :price, :material, :product_id],
    images_attributes: [ :image, :product_id ],
    servizations_attributes: [:coefficient, :product_id, :addservice_id]
    )
end

产品型号(我删除了不相关的部分):

class Product < ActiveRecord::Base
 has_many   :servizations
 has_many   :addservices, through: :servizations

 accepts_nested_attributes_for :servizations

 before_destroy :ensure_not_referenced_by_any_line_item

其他服务模式:

class Addservice < ActiveRecord::Base
    has_many :servizations
    has_many :products, through: :servizations
end

服务模式

class Servization < ActiveRecord::Base
    belongs_to :product
    belongs_to :addservice
end

这是我的edit.html.haml:

=form_for @product do |f|
                =f.label 'Title'
                =f.text_field :title
                %p
                =f.label 'Colors'
                =collection_check_boxes(:product, :color_ids, Color.all, :id, :value )
                %p
                =f.label 'Additional services'
                =collection_check_boxes(:product, :addservice_ids, Addservice.all, :id, :title)
                =f.fields_for :servization do |s|
                    =s.label 'Coefficient'
                    =s.text_field :coefficient
                %p
                    =f.submit class: 'btn btn-default'

我没有问题保存普通服务或只是颜色,但是当我尝试编辑并保存系数时,我收到以下错误:

Processing by ProductsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"jLN59PIOgpaIQtg2/rVYcK/xUOCFzSMLosfUhOslY9tNNhjFbh16Aa1/qT/8u7LHuhNTLGr2SB7b/BitekuDJQ==", "product"=>{"title"=>"Power MI", "color_ids"=>["1", "2", "3", ""], "addservice_ids"=>["1", ""], "servization"=>{"coefficient"=>"1.5"}}, "commit"=>"Update Product", "id"=>"7"}
  Product Load (0.3ms)  SELECT  "products".* FROM "products" WHERE "products"."id" = $1 LIMIT 1  [["id", 7]]
Unpermitted parameter: servization

服务结构:

Servization(id: integer, product_id: integer, addservice_id: integer, coefficient: float, created_at: datetime, updated_at: datetime)

我不明白......我的选项也保存得很好,图像也是如此。但是其他服务拒绝保存。

编辑1: 我想我可能会接近解决方案。问题是表单中的正确链接。这是我到目前为止所提出的:

    =form_for @product do |f|
        %p
            =f.label "Additional Services"
        %br
        -Addservice.all.each do |addservice|
            =check_box_tag "product[addservice_ids][]", addservice.id, @product.addservice_ids.include?(addservice.id)
            =addservice.title
            =text_field_tag "product[servizations][coefficient][]", addservice.servizations.where(product_id: @product.id)[0].coefficient
            %br
        %p
            =f.submit class: 'btn btn-default'

这是补丁请求:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"wD8uMSu0TxvumAWcs1V6GtAFeNgYhbEPEh8HuV8RWucBuk8At6e3jMuldJWxW5Ctxed7FPe+2hprJMuQzn+6GQ==", "product"=>{"title"=>"Флешеченка на тристапяцот гигов", "color_ids"=>["1", "2", "3", ""], "addservice_ids"=>["1", "2"], "servizations"=>{"coefficient"=>["4", "5"]}}, "commit"=>"Update Product", "id"=>"5"}

然而现在我又来了

Unpermitted parameter: servizations

错误

1 个答案:

答案 0 :(得分:1)

问题出在这一行

=f.fields_for :servization do |s|

应该是

=f.fields_for :servizations do |s|

<强> 更新

您应该允许:id 更新 才能正常使用

def product_params
    params.require(:product).permit(
    :title, :description, :advertising_text, :fancy_quote, :hot, :hotpic, :product_size_ids, 
    { volume_ids: [] }, { color_ids: [] }, { addservice_ids: [] }, :category_id, :subcategory_id, 
    options_attributes: [:size, :weight, :price, :material, :product_id],
    images_attributes: [ :image, :product_id ],
    servizations_attributes: [:id, :coefficient, :product_id, :addservice_id]
    )
end