Rails 5 - 从单个实体访问此模型结构的正确方法是什么?

Rails 5 - what is the correct way to access this model structure from a single entity?

我有一个产品和类别模型结构,但是,属于每个产品的属性取决于它们所属的类别。

请注意,这与 STI(单一 table 继承)无关,因为我没有实现继承自 Product 的特定 类(例如 Book < ProductBicycle < 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

想象一个名为 'Rugs' 的类别。地毯有尺寸,所以:

category_attribute.name 将是 'size'

category_attribute.values 将有 3 - 'small'、'medium'、'large'

所以在 `category_attribute' table:

|编号 |姓名 |值

| 1 |尺码 |小

| 2 |尺码 |中

| 3 |尺码 |大

但个别 Rug 产品可能仅在 'small' 有售。

这就是 ProductCategoryAttribute 的原因 -> 我只能分配适用于该特定产品的属性。

我不明白的是我如何 'short-cut' 创建 ActiveRecord 关联。

例如,如果我在内存中加载一个Product,我该如何修改关联以便我可以做到:

product.category_attributes甚至 product.attributes

至return仅适用于该产品的那些。

例如,我知道我可以获得这样的单个属性:

p.product_category_attributes.first.category_attribute

而且显然只有 return 第一个(而且也很笨重)。

我相信有一种方法可以添加方法或范围 - 我想称之为 'attributes' - 这可以解决我的问题,但我对如何进行有点迷茫。

好像attributes已经被ActiveModel保留了?

尝试 1 在这里吠叫错误的树但值得一试,嗯?

Product.rb

  def cat_attributes
    self.product_category_attributes.each do |pca|
      return pca.category_attribute
    end
  end

Returns product_category_attributes,不是 category_attributes

尝试 2

Product.rb

has_many :category_attributes, through: :product_category_attributes

这 return 是我想要的数据,但现在如何将别名命名为更短的名称?

尝试 3

Product.rb

has_many :cat_atts, class_name: 'CategoryAttribute', through: :product_category_attributes, source: :category_attributes

尝试 4

Delete *.*
ReturnTo C#

谢谢。

根据 Rails Guide,您可以使用您的尝试 3 版本。喜欢:

# app/models/product.rb

  has_many :product_category_attributes
  has_many :cat_atts, through: :product_category_attributes, source: :category_attribute