Rails 复杂的模型关联,用户和团队之间的共享文档
Rails Complex Model Association, Shared Document Between Users and Teams
我脑子里有一个复杂的模型关联,想知道如何实现它。这就是我想要完成的。
- 我有一个用户模型和一个文档模型
- 用户可以创建文档。他现在是文档管理员。
- 他可以将其他用户添加到他的文档中,并授予他们编辑者、查看者、管理员等权限
- 他还可以创建一个团队,一组用户,并将多个团队添加到他的文档中。用户已添加到其文档的团队中的每个用户也将拥有权限。一个用户可以属于多个团队。
我对必须设置的关联有点困惑。这是我到目前为止的代码,其中没有包含团队方面:
class User < ApplicationRecord
has_many :participations
has_many :documents, through: :participations
end
class Document < ApplicationRecord
has_many :participations
has_many :users, through: :participations
end
class Participation < ApplicationRecord
belongs_to :user
belongs_to :document
enum role: [ :admin, :editor, :viewer ]
end
我建议以与现有模型类似的方式引入 Team 和 TeamMembership 模型。同时将参与的 belongs_to 关联从 user
更改为多态 participant
.
class Team < ApplicationRecord
has_many :team_memberships
has_many :users, through: :team_memberships
has_many :participations, as: :participant
end
class TeamMembership < ApplicationRecord
belongs_to :team
belongs_to :user
end
class User < ApplicationRecord
has_many :team_memberships
has_many :teams, through: :team_memberships
has_many :participations, as: :participant
end
class Participation < ApplicationRecord
belongs_to :participant, polymorphic: true
belongs_to :document
enum role: [ :admin, :editor, :viewer ]
end
class Document < ApplicationRecord
has_many :participations
# if desired create a users method to conveniently get a list of users with access to the document
def users
@users ||= participations.flat_map do |participation|
case participation.partipant
when User
[participation.participant]
when Team
participation.participant.users
end
end
end
end
我只会添加 has_many :through 关联,因为您发现 benefit/need 拥有它们。除非您有特定的用例,否则这将降低维护它们的复杂性。在 User 具有团队关联的情况下,很明显您可能希望获得用户所属的团队,因为 TeamMembership 对象中没有您可能需要的特定信息决心,真好has_many:through to have.
编辑:添加了 Document
模型。
由于您已经有了一个 participation
模型,您可以将其用作用户和团队之间的连接模型。由于一个 user
可以属于多个团队,而一个文档可以有多个团队,因此您可以使用 has_many through 团队和文档之间的关系。我们将其称为 DocumentTeam
模型。
class User < ApplicationRecord
has_many :participations
has_many :documents, through: :participations
has_many :teams, through: :participations
end
class Participation < ApplicationRecord
belongs_to :document
belongs_to :user
belongs_to :team, optional: true
enum role: [ :admin, :editor, :viewer ]
end
class Team < ApplicationRecord
has_many :participations
has_many :users, through: :participations
has_many :document_teams
has_many :document, through: :document_teams
end
class Document < ApplicationRecord
has_many :participations
has_many :users, through: :participations
has_many :document_teams
has_many :teams, through: :document_teams
end
class DocumentTeam < ApplicationRecord
belongs_to :document
belongs_to :team
end
我脑子里有一个复杂的模型关联,想知道如何实现它。这就是我想要完成的。
- 我有一个用户模型和一个文档模型
- 用户可以创建文档。他现在是文档管理员。
- 他可以将其他用户添加到他的文档中,并授予他们编辑者、查看者、管理员等权限
- 他还可以创建一个团队,一组用户,并将多个团队添加到他的文档中。用户已添加到其文档的团队中的每个用户也将拥有权限。一个用户可以属于多个团队。
我对必须设置的关联有点困惑。这是我到目前为止的代码,其中没有包含团队方面:
class User < ApplicationRecord
has_many :participations
has_many :documents, through: :participations
end
class Document < ApplicationRecord
has_many :participations
has_many :users, through: :participations
end
class Participation < ApplicationRecord
belongs_to :user
belongs_to :document
enum role: [ :admin, :editor, :viewer ]
end
我建议以与现有模型类似的方式引入 Team 和 TeamMembership 模型。同时将参与的 belongs_to 关联从 user
更改为多态 participant
.
class Team < ApplicationRecord
has_many :team_memberships
has_many :users, through: :team_memberships
has_many :participations, as: :participant
end
class TeamMembership < ApplicationRecord
belongs_to :team
belongs_to :user
end
class User < ApplicationRecord
has_many :team_memberships
has_many :teams, through: :team_memberships
has_many :participations, as: :participant
end
class Participation < ApplicationRecord
belongs_to :participant, polymorphic: true
belongs_to :document
enum role: [ :admin, :editor, :viewer ]
end
class Document < ApplicationRecord
has_many :participations
# if desired create a users method to conveniently get a list of users with access to the document
def users
@users ||= participations.flat_map do |participation|
case participation.partipant
when User
[participation.participant]
when Team
participation.participant.users
end
end
end
end
我只会添加 has_many :through 关联,因为您发现 benefit/need 拥有它们。除非您有特定的用例,否则这将降低维护它们的复杂性。在 User 具有团队关联的情况下,很明显您可能希望获得用户所属的团队,因为 TeamMembership 对象中没有您可能需要的特定信息决心,真好has_many:through to have.
编辑:添加了 Document
模型。
由于您已经有了一个 participation
模型,您可以将其用作用户和团队之间的连接模型。由于一个 user
可以属于多个团队,而一个文档可以有多个团队,因此您可以使用 has_many through 团队和文档之间的关系。我们将其称为 DocumentTeam
模型。
class User < ApplicationRecord
has_many :participations
has_many :documents, through: :participations
has_many :teams, through: :participations
end
class Participation < ApplicationRecord
belongs_to :document
belongs_to :user
belongs_to :team, optional: true
enum role: [ :admin, :editor, :viewer ]
end
class Team < ApplicationRecord
has_many :participations
has_many :users, through: :participations
has_many :document_teams
has_many :document, through: :document_teams
end
class Document < ApplicationRecord
has_many :participations
has_many :users, through: :participations
has_many :document_teams
has_many :teams, through: :document_teams
end
class DocumentTeam < ApplicationRecord
belongs_to :document
belongs_to :team
end