Reputation: 6096
I have models User
, Team
, Document
. There's a many-to-many relationship between Users and Teams, and a many-to-many relationship between Teams and Documents, using join tables called TeamMembership
and TeamDocument
respectively.
The relationships in my models look like this:
class Document < ActiveRecord::Base
has_many :team_documents, dependent: :destroy
has_many :teams, through: :team_documents
end
class User < ActiveRecord::Base
has_many :team_memberships, dependent: :destroy, foreign_key: :member_id
has_many :teams, through: :team_memberships
has_many :documents, through: :teams
end
class TeamDocument < ActiveRecord::Base
belongs_to :team
belongs_to :document
end
class TeamMembership < ActiveRecord::Base
belongs_to :team
belongs_to :member, class_name: "User"
end
class Team < ActiveRecord::Base
has_many :team_documents, dependent: :destroy
has_many :documents, through: :team_documents
has_many :team_memberships, dependent: :destroy
has_many :members, through: :team_memberships
end
The idea is that users can belong to many teams, a document can be associated with many teams, and users will only have access to documents that "belong" to at least one team that the user is a member of.
Here's the question: I can use User#documents
to retrieve a list of all the documents that this user is allowed to view. But this will return duplicates if a document is viewable by more than one team which the user is a member of. How can I avoid this?
I know I can remove the duplicates after the fact with @user.documents.uniq
, but as I will never want to include the duplicates in any case, is there a way I can just make #documents
not include duplicates every time?
Upvotes: 0
Views: 217
Reputation: 7937
I don't have nested has_many :through
like yours to test it, but I suspect using uniq
option on your user association would help :
class User < ActiveRecord::Base
has_many :documents, through: :teams, uniq: true
end
Upvotes: 1
Reputation: 44675
You can add a default_scope on Document model:
class Document < ActiveRecord::Base
default_scope group: { documents: :id }
Upvotes: 0