开发者

How do you group a has many through relationship in Rails 3?

开发者 https://www.devze.com 2023-02-11 00:53 出处:网络
I have 3 models: account, discussion and tag (provided by is_taggable) class Account has_many :discussions

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
0

精彩评论

暂无评论...
验证码 换一张
取 消