I have 3 models: account, discussion and tag (provided by is_taggable)
class Account
has_many :discussions
end
class Discussion
belongs_to :account
has_many :tags
is_taggable
end
I want to be able to do current_account.tags, to list all of the tags currently being used by an account's discussions. So...
class Account
has_many :discussions
has_many :tags, :through => :discussions, :source => :taggings
end
Note: the taggings source is for the join table that is_taggable uses to join tags to your taggable model (discussions, in this case...)
The problem with leaving this HM :through this way, is that multiple o开发者_如何学运维ccurrences of the same tag in different discussions will force them to appear the same number of times in this association. So, I thought "no problem, I will group this association on the taggings table's tag_id, so each tag shows up only once.
class Account
has_many :discussions
has_many :tags, :through => :discussions, :source => :taggings, :group => "taggings.tag_id"
end
This doesn't work, further examination of the SQL this generates shows the GROUP BY doesn't appear in the SQL. My question, how do I get this to work?
Some other things I tried:
- Making an instance method, "tags." While this returned my result set properly, it wasn't an AR collection, and so I wasn't able to manipulate it as so. (maybe someone knows how to do this properly?)
- Use the :unique => true option. Sounds like it'd work, but since we are sourcing the :taggings table, that's what it tries to make unique, and all entries in that table are unique (tag_id + taggable_id [our discussion]), nothing changes.
Thanks in advance for any help, and apologies for any iPad-related typos.
Use a named scope on tags, such as this:
scope :account, lambda { |account|
select('DISTINCT taggings.*').
join('discussions on discussions.id = taggings.discussion_id').
where("discussions.account_id = ?", account.id)
}
Then, just call it as:
Tags.account(current_account)
And you'll get back an AR collection. You could also add a method to your Account model that just called that scope on Tags with self, like:
def tags.
Tags.account(self)
end
精彩评论