Rails ActiveRecord 等效于 Laravel ORM `attach()` 多态方法 has_many :through

Rails ActiveRecord equivalent of Laravel ORM `attach()` method for polymorphic has_many :through

我正在从 "Laravel ORM" 过渡到 "Rails Active Record",但我找不到你如何做这样的事情:

$this->people()->attach($person['id'], ['role' => $role]);

Laravel 代码段的解释

People 是通过 $this 通过 Role class 访问的 class 的多态关联。上面的函数,在中间创建一条记录 table (roles/peopleables) 像这样:

id: {{generically defined}}
people_id: $person['id']
role: $role
peopleable_type: $this->type
peopleable_id: $this->id

如何在 Laravel 端定义关联:

class XYZ {
...
    public function people()
    {
        return $this->morphToMany(People::class, 'peopleable')->withPivot('role','id');
    }
...
}

我的努力Ruby

以下是我在 Ruby 中建立关联的方式:

class Peopleable < ApplicationRecord
    belongs_to :people
    belongs_to :peopleable, polymorphic: true
end

class People < ApplicationRecord
    has_many :peopleables
end

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

我看到了操作<<,但我不知道是否有任何方法可以在触发此操作时在枢轴table 上设置一个附加值。 [在这种情况下 rolespeopleables tables;我在此应用程序中交替使用这两个术语。]

PS。所以,基本上问题是如何在 ActiveRecord 的多态多关联中定义枢轴 table 的附加值,并在启动附件关系时动态设置这些值

功能描述

我们的应用有无限的[一般来说,并不是说没有计算的限制!]内容类型:post、小说、诗歌等

这些内容类型中的每一种都可以与扮演特定角色的个人相关联:编辑、作者、译者等。

因此,例如:

X is the translator of Post#1. X, Y and Z are authors of Post#1.

有一个独特的 People 模型,每个内容类型都有自己独特的模型 [例如:PostPoem 等]。

:through 的意思是指 'Role class' 或者 'the pivot table' [随便你怎么理解] 上面记录了多态关联

除了简单的多态关系信息外,还有一种角色被记录在pivot上table。

例如,X既是Post#1的作者又是译者,所以有两行people_idpeopleable_typepeopleable_id , 但是它们对 role.

有不同的值
  1. Rails 是 'convention over configuration'。模特必须是单数 'Person'.

  2. A​​ctiveRecord 有has_many ...通过和多态关联

  3. "Assignable" 和 "Assignments" 比 "peoplable"

  4. 更自然
class Person < ApplicationRecord
  has_many :assignments, as: :assignable
  has_many :roles, through: :assignments
end

class Role < ApplicationRecord
  has_many :assignments
  has_many :people, through: :assignments
end

class Assignment
  belongs_to :role
  belongs_to :assignable, polymorphic: true
end

你可以阅读更多Rails has_many :through Polymorphic Association by Sean C Davis

根据我对你的描述的理解,我认为你有这个模型(我会把名字改成我理解的,希望它足够清楚):

class Person < ApplicationRecord # using singular for models
  has_many :person_roles
end

class Poem < ApplicationRecord
  has_many :person_roles, as: :content
end

class Novel < ApplicationRecord
  has_many :person_roles, as: :content
end

etc...

class PersonRole < ApplicationRecord
  belongs_to :person
  belongs_to :content, polymorphic: true

  # you should have a "role" column on your table
end

因此,Person 通过具有特定角色的连接模型 PersonRole 关联到 "content"(小说、诗歌等)。作为某个小说的作者和某个诗歌的编辑的 Person 将有两个 PersonRole 记录。

因此,如果您有一个人并且想在某些内容上分配一个新角色,您可以这样做:

person.person_roles.create(role: :author, content: some_poem)

or

PersonRole.create(person: person, role: :author, content: some_poem)

or

some_poem.person_roles.create(person: person, role: :author)

这里有两件事在起作用:"belongs_to :content, polymorphic: true" 涵盖了作为多态关联的部分。然后你有 "PersonRole" table 涵盖了你知道的部分 "pivot table" (在 rails 上加入 table/model)。

请注意 rails 中的 :through 有其他含义,您可能想要获取用户是其作者的所有诗歌,然后您可以有一个 "has_many :poems, through: :person_roles" 关联(这实际上不起作用,它比这种情况更复杂,因为你有一个多态关联,你需要用一些额外的选项配置关联,比如 sourcescope 才能工作,我只是将其用作我们理解为 has many :through 关联的示例。