[scope :tagged] Avoiding repeated results

Hello,

I've a usually structure with Post has_many Tags through Taggings. All works well and clean. But I'm having problems with the next scope on Post:

scope :tagged, lambda {|tag_id| joins(:taggings).where(:taggings => {:tag_id => tag_id}) }

All works fine for call of only one Tag like: Post.tagged("sport") . The problem comes when you want to show the adverts that have any tag OR other, like well: Post.tagged(%w{sport people}). Then, the INNER JOIN do that I may get repeated results of Post. For example, if I may have two Post with "sport" and "people" tag each one, with the previous call, I would get 4 results.

Thanks for help.

I'm trying to use "select('DISTINCT *')" but it doesn't work. Sure, de INNER JOIN between Post and Tagging result of table that all rows are distinct. If we supost the next:

Posts Table ID TITLE 1 "Foo" 2 "FooFaa"

TAGGINGS Table ID POST_ID TAG_ID 1 1 1 1 1 2 1 2 1 1 2 2

Using "select("DISTINCT posts.id, posts.title")" method I think I could get it but it isn't clean. Really, my Posts table have a lot of attributtes. Some advice? Thanks.

Haven't tried it, but maybe grouping on posts.id would do the right thing?

--Matt Jones

Haven't tried it, but maybe grouping on posts.id would do the right thing?

--Matt Jones

Hello Matt, thanks for the answer. I've try it and it works fine except when you call to "count" method later. I've solve it well:

scope :finded, lambda {|id| where(:id => id)} scope :tagged, lambda {|tag_id| select('posts.id').joins(:taggings).where(:taggings => {:tag_id => tag_id}) }

And then, for call the method, I do this:

@posts = Post.finded(Post.tagged(params[:tag_id]).uniq.map {|x| x.id})

The finded scope is for return an ActiveRecord array instead do the common find method. Yes, it's not too smart solution but, for the moment, it's working and while I'm trying to find a more clean solution and I'm attentive for your answers and advices. Thanks!