Rails HABTM设置,模型对象,& join_table插入控制器设置

时间:2018-04-15 22:31:13

标签: ruby-on-rails model controller has-and-belongs-to-many jointable

我有以下设置。

1个产品有很多product_types。 许多product_types有1种类型。 我对文档的理解中的HABTM关系。

我的模特

class Product < ApplicationRecord
  has_and_belongs_to_many :types
end

class Type < ApplicationRecord
  has_and_belongs_to_many :products
end

我有一个连接表迁移

class CreateJoinTableProductTypes < ActiveRecord::Migration[5.1]
  def change
    create_join_table :products, :types do |t|
      t.index :product_id
      t.index :type_id
    end
  end
end

我创建了一个表单 - 希望正确创建,现在我在表单提交上发送了以下参数:

"product"=>{"name"=>"Product A", "description"=>"A cool product", "image_dir_path"=>"./",
"type"=>{"id"=>"1"}},"commit"=>"Create Product"}

我想知道 1)在表单和控制器中提交用于创建产品的参数的最佳/ rails约定是什么?

2)我是如何获得的,将记录插入到连接表中?

我有以下方法来获取参数

def product_params
  params.require(:product).permit(:name, :description, :image_dir_path, :type,)
end

但即便如此,我还可以在日志中看到未经许可的参数:type

目前我的控制器只有:

@product = Product.new(product_params)

我非常感谢有关创建此对象的rails方法的任何建议。我已经阅读了HABTM的api文档,但在模型对象中没有看到任何内容,或者我应该如何在控制器中处理这些内容。

谢谢!

2 个答案:

答案 0 :(得分:2)

ActieRecord为所有has_manyhas_and_belongs_to_many关联生成_ids个setter和getter。

# creates 3 rows in products_types if they do not exist
# also deletes any rows not in the array
@product.update(type_ids: [1,2,3])

这些与form options helpers一起用于指定关联:

<%= form_for(@product) do |f| %>
  <div class="field">
    <%= f.label :type_ids %>
    <%= f.collection_select :type_ids, Type.all, :id, :name, multiple: true %>
  </div>
  ...
<% end %>

要将参数列入白名单,您将其作为选项传递,其值为[],允许包含任何标量类型的数组。

def product_params
  params.require(:product).permit(:name, :description, :image_dir_path, type_ids: [])
end
  

2)我是如何获得的,将记录插入到连接表中?

使用has_and_belongs_to_many关联,您只能间接插入/访问行。

例如:

@product.types 
# or
@product.types << Type.first
# or
@product.types.create(name: 'Foo')

或者使用前面提到的type_ids setter / getter。这与has_many through:的关键区别在于,您可以直接查询或创建连接模型。

答案 1 :(得分:1)

在最后评论之后,我意识到类型关系不是HABTM,而是产品中的一对多。我有另一个型号尺寸,在HABTM中有产品。

我的模特看起来像这样:

class Product < ApplicationRecord
  belongs_to :product_type
  has_and_belongs_to_many :sizes
end

class Size < ApplicationRecord
  has_and_belongs_to_many :products
end

加入表是:

class CreateJoinTableProductSize < ActiveRecord::Migration[5.1]
  def change
    create_join_table :cakes, :sizes do |t|
      t.index [:product_id, :size_id]
    end
  end
end

尺寸表是默认值 产品表是

class CreateProducts < ActiveRecord::Migration[5.1]
  def change
    create_table :products do |t|
      t.string :name
      t.string :description
      t.references :product_type, foreign_key: true

      t.timestamps
    end
  end
end

我的控制器是默认设置 - 我只是将以下参数列入白名单

def cake_params   params.require(:product).permit(:name,:description,:product_type_id,{:size_ids =&gt; []}) 端

我的_form有以下

  <div class="field">
    <%= form.label :product_type_id %>
    <%= form.collection_select(:product_type_id, ProductType.all, :id, :name) %>
  </div>

  <div class="field">
    <%= form.label :product_size %>
    <%= collection_check_boxes(:product, :size_ids, Size.all, :id, :name) %>
  </div>

现在我可以提交表单,编辑它并正确显示所有值!