代码之家  ›  专栏  ›  技术社区  ›  jimgug

Rails HABTM设置、模型对象和join\u表格插入控制器设置

  •  0
  • jimgug  · 技术社区  · 6 年前

    我有以下设置。

    1产品有多种product\u类型。 许多product\u类型有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
    

    但即使这样,我也可以在logs unpermitted参数中看到:type

    目前,我的控制器只有:

    @product = Product.new(product_params)
    

    如果您对rails创建此对象的方式有任何建议,我将不胜感激。我已经阅读了HABTM的api文档,但没有看到任何关于模型对象的内容,也没有看到我应该如何在控制器中处理这些内容。

    谢谢

    2 回复  |  直到 6 年前
        1
  •  4
  •   max Mike Williams    6 年前

    ActiveRecord生成 _ids 所有人的setters和getter has_many has_and_belongs_to_many 关联。

    # 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\u和\u beliens\u to\u many 关联您只能间接插入/访问行。

    例如:

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

    或使用 type_ids 前面提到的setter/getter。这与 has_many through: 其中有一个可以直接查询或创建的联接模型。

        2
  •  2
  •   jimgug    6 年前

    在max的评论之后,我意识到类型关系不是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\u参数 参数。要求(:产品)。许可证(:name,:description,:product\u type\u id,{:size\u id=>[]}) 终止

    我的表单有以下内容

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

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