【发布时间】:2020-10-25 12:59:49
【问题描述】:
我有一个产品和类别模型结构,但是,属于每个产品的属性取决于它们所在的类别。
请注意,这与 STI(单表继承)无关,因为我没有实现从 Product 继承的特定类(例如 Book < Product、Bicycle < Product 等)
我有以下模型类(仅简化为相关代码):
class Product < ApplicationRecord
# Relationships
belongs_to :subcategory
delegate :category, to: :subcategory, allow_nil: true
has_many :product_category_attributes
end
class Category < ApplicationRecord
# Relationships
has_many :subcategories, dependent: :destroy
has_many :products, through: :subcategories
has_many :category_attributes, dependent: :destroy
end
class CategoryAttribute < ApplicationRecord
# Relationships
belongs_to :category
has_many :product_category_attributes, dependent: :destroy
end
class ProductCategoryAttribute < ApplicationRecord
# Relationships
belongs_to :product
belongs_to :category_attribute
end
这行得通,但是……请耐心等待!
这是类别层次结构的迁移:
class CreateCategories < ActiveRecord::Migration[5.1]
def change
create_table :categories, id: :uuid do |t|
t.string :name
t.timestamps
end
end
end
class CreateCategoryAttributes < ActiveRecord::Migration[5.1]
def change
create_table :category_attributes, id: :uuid do |t|
t.references :category, type: :uuid, foreign_key: true, index: true
t.string :name
t.string :value
t.timestamps
end
end
end
class CreateProductCategoryAttributes < ActiveRecord::Migration[5.1]
def change
create_table :product_category_attributes, id: :uuid do |t|
t.references :product, type: :uuid, foreign_key: true
t.references :category_attribute, type: :uuid, foreign_key: true
t.timestamps
end
add_index :product_category_attributes, [:product_id, :category_attribute_id], unique: true, name: 'index_product_category_attributes_on_fks'
end
end
想象一个名为“地毯”的类别。地毯有大小,所以:
category_attribute.name 将是“大小”
和
category_attribute.values 将有 3 - 'small'、'medium'、'large'
所以在`category_attribute'表中:
|编号 |姓名 |价值
| 1 |尺寸 |小
| 2 |尺寸 |中等
| 3 |尺寸 |大
但单个地毯产品可能仅以“小”的形式提供。
这就是ProductCategoryAttribute 的原因 -> 我只能分配适用于该特定产品的属性。
我不明白如何“快捷”创建 ActiveRecord 关联。
例如,如果我在内存中加载一个Product,我该如何修改关联以便我可以这样做:
product.category_attributes 甚至
product.attributes
只返回适用于该产品的那些。
作为一个例子,我知道我可以得到这样的单个属性:
p.product_category_attributes.first.category_attribute
这显然只返回第一个(而且也很笨拙)。
我相信有一种方法可以添加方法或范围 - 我想称之为“属性” - 可以解决我的问题,但我对如何继续操作有点迷茫。
attributes好像已经被ActiveModel保留了?
尝试 1 在这里找错树了,但值得一试,嗯?
产品.rb
def cat_attributes
self.product_category_attributes.each do |pca|
return pca.category_attribute
end
end
返回product_category_attributes,而不是category_attributes
尝试 2
产品.rb
has_many :category_attributes, through: :product_category_attributes
这将返回我想要的数据,但现在我如何将名称别名为更短的名称?
尝试 3
产品.rb
has_many :cat_atts, class_name: 'CategoryAttribute', through: :product_category_attributes, source: :category_attributes
尝试 4
Delete *.*
ReturnTo C#
谢谢。
【问题讨论】:
标签: ruby-on-rails model associations