【问题标题】:Category and Product mapping in activerecordactiverecord 中的类别和产品映射
【发布时间】:2011-10-19 14:14:21
【问题描述】:

使用 RoR ORM,您将如何映射此模型。

Categories
-id

Products
-id

CategoriesProducts
-category_id
-product_id

所以我想执行如下查询:

category.products.all
product.category.id

在 Rails 中,您如何决定使用关系的哪一侧将产品添加到类别中?

会是这样吗:

category.add_product(product)

product.add_category(category)

如果我想获取 ID 为 234,24,431,214 的所有类别和产品,有没有办法在不遇到 n+1 查询问题的情况下做到这一点?

【问题讨论】:

标签: ruby-on-rails activerecord


【解决方案1】:

最简单的方法是使用has_and_belongs_to_many。确保在创建 CategoriesProucts 表时,您创建了没有 id 的迁移文件:

create_table :categories_products, :id => false do |t|

那么你的分类模型应该是这样的:

class Category < ActiveRecord::Base
  has_and_belongs_to_many :products
end

您的产品模型应如下所示:

class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

这是另一种方法。如果您希望稍后对修改进行更多控制,这也将起作用。在您的 CategoriesProduct 模型上:

class CategoriesProduct < ActiveRecord::Base
  belongs_to :category
  belongs_to :product
end

在您的类别模型上:

class Category < ActiveRecord::Base
  has_many :categories_products
  has_many :products, :through => :categories_products
end

在您的产品型号上:

class Product < ActiveRecord::Base
  has_many :categories_products
  has_many :categories, :through => :categories_products
end

那么你应该可以做到:

Category.create(:name => "Cat1")
Category.first.products.create(:name => "Prod1")
Product.first.categories.create(:name => "Cat2")

等等……

This infograph 可能有助于将概念可视化。

【讨论】:

  • categoriesproducts 应该是一个模型还是只是一个连接表?
  • 我将您的描述解释为您使用categoriesproducts 作为连接表。难道你不能在Product 模型上放置一个category_id 字段,然后拥有我在答案末尾描述的关系吗?
【解决方案2】:

创建表 categories_products、categories 和 products,并为 Category 和 Products 创建 modal。

在两个模态中都有关系 has_and_belongs_to_many。这应该允许您使用@category.products(获取特定类别的所有产品)和@product.categories(获取该产品的所有类别)之类的方法。

还可以看看这些: http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many

【讨论】:

    【解决方案3】:

    在决定如何重新获取数据方面,这完全取决于您以及您从什么角度获取数据。

    例如,在 categories_controller 中,将类别传递给产品会更有意义,反之亦然。

    要获取特定类别的所有产品,您可以将其组合起来:

    Category.where("id IN (?)", [1,2,3,4,5,6]).includes(:products)
    

    (或类似的,我没有测试过这个)。这将对类别进行一次查询,对产品进行一次查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多