ActiveRecord 与两个不同模型的关联
ActiveRecord associations with two different models
我很难思考应该如何配置表 + 关联。
我有一个 Lawsuit
模型。诉讼 has_many
方(被告、原告、律师等)。反过来,派对可以是 Person
或 Company
。最终,我希望能够得到:
- 一个人的官司(
@person.lawsuits
);
- 一家公司的官司(
@company.lawsuits
);和
- 诉讼当事人(
@lawsuit.parties
),可以是people
或companies
。
这就是我目前设置表格 + 模型的方式:
人
| id | fname | lname | date_of_birth |
| -- | ------ | ----- | ------------- |
| 1 | John | Smith | 1974-02-04 |
| 2 | George | Glass | 1963-07-29 |
公司
| id | name | duns | ticker | address |
| -- | --------- | --------- | ------ | ------------ |
| 1 | Acme Inc. | 239423243 | ACME | 123 Main St. |
诉讼
| id | jurisdiction | court | case_no | title |
| -- | ------------ | ----- | ---------- | --------------------------- |
| 1 | federal | SDNY | 18-CV-1234 | Smith v. Glass, Acme, et al |
lawsuit_parties
| id | lawsuit_id | person_id | company_id | role |
| -- | ---------- | --------- | ---------- | --------- |
| 1 | 1 | 1 | | plaintiff |
| 2 | 1 | 2 | | defendant |
| 3 | 1 | | 1 | defendant |
# models/lawsuit.rb:
class Lawsuit < ApplicationRecord
has_many :lawsuit_parties
def parties
self.lawsuit_parties
end
def defendants
self.parties(where(lawsuit_parties: {role: 'defendant'})
end
def plaintiffs
self.parties(where(lawsuit_parties: {role: 'plaintiff'})
end
def attorneys
self.parties(where(lawsuit_parties: {role: 'attorney'})
end
end
# models/lawsuit_party.rb
class LawsuitParty < ApplicationRecord
belongs_to :person
belongs_to :company
end
# models/person.rb
class Person < ApplicationRecord
has_many :lawsuit_parties
has_many :lawsuits, through: :lawsuit_parties
end
# models/company.rb
class Company < ApplicationRecord
has_many :lawsuit_parties
has_many :lawsuits, through: :lawsuit_parties
end
如有任何帮助,我们将不胜感激……
您的方向是正确的,但您需要介绍一个 polymorphic relationship onto your Join Model to get this type of modeling to work. An Enum can handle differentiating between Defendants and Plaintiffs,并免费提供几个 scopes/methods。
class LawsuitParty < ApplicationRecord
belongs_to :lawsuit
belongs_to :partiable, polymorphic: true
enum role: [:defendant, :plaintiff]
end
您需要编写迁移以将您的 lawsuit_parties
table 更改为以下列(所有 Rails 约定名称):
partiable_id = Integer
partiable_type = String
role = String
lawsuit_parties
| id | lawsuit_id | partiable_id | partiable_type | role |
| -- | ---------- | ------------ | -------------- | ----------|
| 1 | 1 | 1 | Person | defendant |
| 2 | 1 | 2 | Company | plaintiff |
| 3 | 1 | 1 | Company | defendant |
接下来,告诉 Rails Person
和 Company
记录与许多使用 has_many
的 :as
的 Lawsuit
相关联选项。
class Person < ApplicationRecord
has_many :lawsuit_parties, as: :partiable
has_many :lawsuits, through: :lawsuit_parties
end
将相同的 has_many :lawsuit_parties, as: :partiable
添加到公司,或以后可能出现的任何其他模型(即 Judge
或 JuryMember
)。
像这样设置 LawsuitParty 后,您应该就万事大吉了。
我很难思考应该如何配置表 + 关联。
我有一个 Lawsuit
模型。诉讼 has_many
方(被告、原告、律师等)。反过来,派对可以是 Person
或 Company
。最终,我希望能够得到:
- 一个人的官司(
@person.lawsuits
); - 一家公司的官司(
@company.lawsuits
);和 - 诉讼当事人(
@lawsuit.parties
),可以是people
或companies
。
这就是我目前设置表格 + 模型的方式:
人
| id | fname | lname | date_of_birth |
| -- | ------ | ----- | ------------- |
| 1 | John | Smith | 1974-02-04 |
| 2 | George | Glass | 1963-07-29 |
公司
| id | name | duns | ticker | address |
| -- | --------- | --------- | ------ | ------------ |
| 1 | Acme Inc. | 239423243 | ACME | 123 Main St. |
诉讼
| id | jurisdiction | court | case_no | title |
| -- | ------------ | ----- | ---------- | --------------------------- |
| 1 | federal | SDNY | 18-CV-1234 | Smith v. Glass, Acme, et al |
lawsuit_parties
| id | lawsuit_id | person_id | company_id | role |
| -- | ---------- | --------- | ---------- | --------- |
| 1 | 1 | 1 | | plaintiff |
| 2 | 1 | 2 | | defendant |
| 3 | 1 | | 1 | defendant |
# models/lawsuit.rb:
class Lawsuit < ApplicationRecord
has_many :lawsuit_parties
def parties
self.lawsuit_parties
end
def defendants
self.parties(where(lawsuit_parties: {role: 'defendant'})
end
def plaintiffs
self.parties(where(lawsuit_parties: {role: 'plaintiff'})
end
def attorneys
self.parties(where(lawsuit_parties: {role: 'attorney'})
end
end
# models/lawsuit_party.rb
class LawsuitParty < ApplicationRecord
belongs_to :person
belongs_to :company
end
# models/person.rb
class Person < ApplicationRecord
has_many :lawsuit_parties
has_many :lawsuits, through: :lawsuit_parties
end
# models/company.rb
class Company < ApplicationRecord
has_many :lawsuit_parties
has_many :lawsuits, through: :lawsuit_parties
end
如有任何帮助,我们将不胜感激……
您的方向是正确的,但您需要介绍一个 polymorphic relationship onto your Join Model to get this type of modeling to work. An Enum can handle differentiating between Defendants and Plaintiffs,并免费提供几个 scopes/methods。
class LawsuitParty < ApplicationRecord
belongs_to :lawsuit
belongs_to :partiable, polymorphic: true
enum role: [:defendant, :plaintiff]
end
您需要编写迁移以将您的 lawsuit_parties
table 更改为以下列(所有 Rails 约定名称):
partiable_id = Integer
partiable_type = String
role = String
lawsuit_parties
| id | lawsuit_id | partiable_id | partiable_type | role |
| -- | ---------- | ------------ | -------------- | ----------|
| 1 | 1 | 1 | Person | defendant |
| 2 | 1 | 2 | Company | plaintiff |
| 3 | 1 | 1 | Company | defendant |
接下来,告诉 Rails Person
和 Company
记录与许多使用 has_many
的 :as
的 Lawsuit
相关联选项。
class Person < ApplicationRecord
has_many :lawsuit_parties, as: :partiable
has_many :lawsuits, through: :lawsuit_parties
end
将相同的 has_many :lawsuit_parties, as: :partiable
添加到公司,或以后可能出现的任何其他模型(即 Judge
或 JuryMember
)。
像这样设置 LawsuitParty 后,您应该就万事大吉了。