I have a Ruby app which uses Ramaze and Sequel.
I have the classes Tag
and Tagging
which have this relationship:
class Tag < Sequel::Model
one_to_many :taggings, :class => 'Thoth::Tagging'
class Tagging < Sequel::Model(:taggings)
many_to_one :tag, :class => 'Thoth::Tag'
I want to return a list of tags in order of popularity, the ones that have the most taggings (filtering out any that have less than three taggings). I'm doing that this way:
tags = .left_outer_join(:taggings, :tag_id => :id).group(:tag_id).having("count(*) > 2").order("count(*) desc").all
This does return what seem to be tag objects, but when I call .id
on them, I get the id of a tagging that points to the tag, rather than the tag itself.
On closer inspection, the results are quite different from a regular find:
> tag_regular = Tag[2]
=> #<Thoth::Tag @values={:title=>nil, :position=>nil, :parent_id=>1, :name=>"academic", :id=>2}>
> tag_from_join = Tag.join(:taggings, :tag_id => :id).group(:tag_id).having("count(*) > 2").order("count(*) desc").all.select{|tag| tag.name == "academic"}.first
=> #<Thoth::Tag @values={:tag_id=>2, :post_id=>5, :title=>nil, :position=>nil, :parent_id=>1, :name=>"academic", :id=>1611, :created_at=>nil}>
In both cases I get a Thoth::Tag, but the values are quite different, based on the different fields in the join I suppose.
All I actually need to do is get a list of regular tag objects sorted by the number of taggings, but in an efficient single-query way. Is there a better way?