Rails - has_many through, STI, and scope



我有以下模型:

create_table :production_actions do |t|
t.string :name
t.string :key
end
create_table :production_attributes do |t|
t.string :name
t.string :key
t.string :type
end
create_table :production_items do |t|
t.timestamps
end
create_table :line_items_production_items do |t|
t.references :line_item, null: false
t.references :production_item, null: false
end
add_index(:line_items_production_items, [:line_item_id, :production_item_id], unique: true, name: 'line_items_production_items_unique')
create_table :production_attributes_production_items do |t|
t.references :production_attribute, null: false, index: {name: 'production_items_on_production_attribute_id'}
t.references :production_item, null: false, index: {name: 'production_attributes_on_production_item_id'}
end
add_index(:production_attributes_production_items, [:production_attribute_id, :production_item_id], unique: true, name: 'production_attributes_production_items_unique')
create_table :production_actions_production_items do |t|
t.references :production_action, null: false, index: {name: 'production_items_on_production_action_id'}
t.references :production_item, null: false, index: {name: 'production_actions_on_production_item_id'}
end
add_index(:production_actions_production_items, [:production_action_id, :production_item_id], unique: true, name: 'production_actions_production_items_unique')
class ProductionAttributeProductionItem < ApplicationRecord
belongs_to :production_attribute, class_name: "ProductionAttribute::Base"
belongs_to :production_item, class_name: "ProductionItem::Base"
end

module ProductionItem
class Base < ApplicationRecord
self.table_name = "production_items"
has_many :production_attribute_production_items, class_name: "ProductionAttributeProductionItem"
has_many :production_attributes, class_name: "ProductionAttribute::Base", through: :production_attribute_production_items
end
module ProductionAttribute
class Base < ApplicationRecord
self.table_name = "production_attributes"

end
end
module ProductionAttribute
class PaperType < ProductionAttribute::Base
end
end
module ProductionItem
class Paper < ProductionItem::Base
has_one :paper_type, -> { where(type: "ProductionAttribute::PaperType")},
class_name: "ProductionAttribute::PaperType", foreign_key: :product_attribute_id,
through: :production_attributes, inverse_of: :product_attribute
end
end

有许多类型的production_items都通过STI保存在一个表中。还有许多类型的production_attributes都通过STI保存在一个表中。一个production_item有(并属于)多个production_attributes。基于子类,我想基于production_item的类型创建特定的product_attribute关联。例如,paper production_item将具有paper_type product_attribute。

我的问题是我正试图获得特定范围的协会,如paper.paper_type的工作,但我有一个艰难的时间。如果我做下面的事情,我得到一个错误:

[1] pry(main)> p = ProductionItem::Paper.new
(0.3ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
=> #<ProductionItem::Paper:0x00005602a669b528
id: nil,
created_at: nil,
updated_at: nil>
[2] pry(main)> p.paper_type
ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) "paper_type" or :paper_type in model ProductionAttribute::Base. Try 'has_many :paper_type, :through => :production_attributes, :source => <name>'. Is it one of jobs?
from /home/USERNAME/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activerecord-5.2.4.4/lib/active_record/reflection.rb:920:in `check_validity!'

我试了几样东西都没有运气。知道为什么这不起作用吗?

是否将外键存储在数据库中的模型中?

要使用belongs_to, has_many和has_one,您需要以某种方式将这些值存储在数据库中。

例如,在ProductionItem中,您不一定需要存储其他对象的id(这可能很有趣,但它将类似于数组)。但是,如果您决定不这样做,则必须将每个ProductionItem的id保存在属于它的对象中。

最新更新