Activerecord 活动记录,多态性与STI有许多联系
我有一些问题与多态性有很多通过与性传播感染。让我解释一下我想做什么: 假设我有一份合同。一份合同可以有多家公司作为协议的当事方,即一份合同可以有多个许可方作为合同中授予权利的一方,多个被许可方作为合同下接受权利的一方。许可方和被许可方都是可以成为多个合同当事人的公司 到目前为止,我有以下代码:Activerecord 活动记录,多态性与STI有许多联系,activerecord,has-many-through,polymorphic-associations,single-table-inheritance,sti,Activerecord,Has Many Through,Polymorphic Associations,Single Table Inheritance,Sti,我有一些问题与多态性有很多通过与性传播感染。让我解释一下我想做什么: 假设我有一份合同。一份合同可以有多家公司作为协议的当事方,即一份合同可以有多个许可方作为合同中授予权利的一方,多个被许可方作为合同下接受权利的一方。许可方和被许可方都是可以成为多个合同当事人的公司 到目前为止,我有以下代码: #contract.rb class Contract < ApplicationRecord has_many :relationships, dependent: :destroy ha
#contract.rb
class Contract < ApplicationRecord
has_many :relationships, dependent: :destroy
has_many :companies, through: :relationships
has_many :licensors, through: :relationships, source: :party, source_type: "Licensor"
has_many :licensees, through: :relationships, source: :party, source_type: "Licensee"
end
#relationship.rb
class Relationship < ApplicationRecord
belongs_to :contract
belongs_to :party, polymorphic: true
end
#company.rb
class Company < ApplicationRecord
has_many :relationships, as: :party, dependent: :destroy
has_many :contracts, through: :relationships
end
#licensor.rb
class Licensor < Company
end
#licensee.rb
class Licensee < Company
end
然后,以下步骤将起作用:
c.licensors # results in...
Licensor Load (1.1ms) SELECT "companies".* FROM "companies" INNER JOIN "relationships" ON "companies"."id" = "relationships"."party_id" WHERE "relationships"."contract_id" = $1 AND "relationships"."party_type" = $2 LIMIT $3 [["contract_id", 1], ["party_type", "Licensor"], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Licensor id: 1, name: "The Licensor Company", created_at: "2018-02-14 19:46:19", updated_at: "2018-02-14 19:46:19">]>
c.licensees # results in...
Licensee Load (1.3ms) SELECT "companies".* FROM "companies" INNER JOIN "relationships" ON "companies"."id" = "relationships"."party_id" WHERE "relationships"."contract_id" = $1 AND "relationships"."party_type" = $2 LIMIT $3 [["contract_id", 1], ["party_type", "Licensee"], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Licensee id: 2, name: "Some Licensee Company", created_at: "2018-02-14 19:46:19", updated_at: "2018-02-14 19:46:19">]>
因此,许可方和被许可方被正确创建,并且他们的party_类型被正确设置
不幸的是,以下情况不起作用:
lor = Licensor.first
lor.contracts # which results in...
Contract Load (0.9ms) SELECT "contracts".* FROM "contracts" INNER JOIN "relationships" ON "contracts"."id" = "relationships"."contract_id" WHERE "relationships"."party_id" = $1 AND "relationships"."party_type" = $2 LIMIT $3 [["party_id", 1], ["party_type", "Company"], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy []>
如您所见,我无法查询特定许可方或被许可方的合同列表。这似乎是因为我当前的设置导致查询的公司类型为party_。我认为这是因为许可方和被许可方都是从公司继承的
在许可方或被许可方的模型中,是否有办法通过关联来设置Has Many中的party_类型
任何帮助都将不胜感激。您可以在此处使用REW。在公司中,定义与以下关联范围的关系:
has_many :relationships, ->(x) { rewhere(party_type: x.class.name) }, as: :party, dependent: :destroy
您可以在连接中看到正在查询的许可方类型:
>> l = Licensor.first
Licensor Load (1.4ms) SELECT "companies".* FROM "companies" WHERE "companies"."type" IN ('Licensor') ORDER BY "companies"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Licensor id: 1, name: "The Licensor Company", type: "Licensor", created_at: "2018-02-23 00:38:13", updated_at: "2018-02-23 00:38:13">
>> l.contracts
Contract Load (1.9ms) SELECT "contracts".* FROM "contracts" INNER JOIN "relationships" ON "contracts"."id" = "relationships"."contract_id" WHERE "relationships"."party_id" = $1 AND "relationships"."party_type" = $2 LIMIT $3 [["party_id", 1], ["party_type", "Licensor"], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Contract id: 1, name: "Test Contract", created_at: "2018-02-23 00:38:13", updated_at: "2018-02-23 00:38:13">]>
没有专家,但也许在“属于”一侧设置“反向”可以有所帮助?反向关联的自动猜测使用基于类名称的启发式方法,因此它可能不适用于所有关联,尤其是具有非标准名称的关联-
>> l = Licensor.first
Licensor Load (1.4ms) SELECT "companies".* FROM "companies" WHERE "companies"."type" IN ('Licensor') ORDER BY "companies"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Licensor id: 1, name: "The Licensor Company", type: "Licensor", created_at: "2018-02-23 00:38:13", updated_at: "2018-02-23 00:38:13">
>> l.contracts
Contract Load (1.9ms) SELECT "contracts".* FROM "contracts" INNER JOIN "relationships" ON "contracts"."id" = "relationships"."contract_id" WHERE "relationships"."party_id" = $1 AND "relationships"."party_type" = $2 LIMIT $3 [["party_id", 1], ["party_type", "Licensor"], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Contract id: 1, name: "Test Contract", created_at: "2018-02-23 00:38:13", updated_at: "2018-02-23 00:38:13">]>