[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 J.

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!

On Jun 6, 4:22pm, danimashu [email protected] wrote:

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.

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

–Matt J.