【问题标题】:Rails 5 - what is the correct way to access this model structure from a single entity?Rails 5 - 从单个实体访问此模型结构的正确方法是什么?
【发布时间】:2020-10-25 12:59:49
【问题描述】:

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

请注意,这与 STI(单表继承)无关,因为我没有实现从 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

想象一个名为“地毯”的类别。地毯有大小,所以:

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


    【解决方案1】:

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

    # app/models/product.rb
    
      has_many :product_category_attributes
      has_many :cat_atts, through: :product_category_attributes, source: :category_attribute
    

    【讨论】:

    • 你刚刚打败了我,我的尝试 5 和你的答案一样!干得好先生:)
    • 我只是稍微修改了一下。你的source 声明是错误的。谢谢,很高兴为您提供帮助!
    猜你喜欢
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    相关资源
    最近更新 更多