首页 > 解决方案 > ActiveRecord 与两个不同模型的关联

问题描述

我很难弄清楚我应该如何配置我的表+关联。

我有一个Lawsuit模型。诉讼has_many各方(被告、原告、律师等)。反过来,一方可以是 aPerson或 a Company。最终,我希望能够得到:

这就是我目前设置表+模型的方式:

人们

| 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 |

诉讼当事人

| 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

任何帮助您将不胜感激……</p>

标签: ruby-on-railsrubyactiverecordruby-on-rails-5polymorphic-associations

解决方案


您在正确的轨道上,但您需要在您的连接模型中引入多态关系才能使这种类型的建模工作。 枚举可以处理被告和原告之间的区分,并免费提供您要求的几种范围/方法。

class LawsuitParty < ApplicationRecord
    belongs_to :lawsuit
    belongs_to :partiable, polymorphic: true

    enum role: [:defendant, :plaintiff]
end

您需要编写迁移以将lawsuit_parties表更改为以下列(所有 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 |

接下来,告诉 RailsPersonCompanyrecords 与许多Lawsuit's using has_many':as选项相关联。

class Person < ApplicationRecord
    has_many :lawsuit_parties, as: :partiable
    has_many :lawsuits, through: :lawsuit_parties
end

将其添加has_many :lawsuit_parties, as: :partiable到 Company 或以后可能出现的任何其他模型(即JudgeJuryMember)。

一旦你有这样的诉讼派对设置,你应该一切准备就绪。


推荐阅读