续集加入:“。if”返回另一个表的id

时间:2013-10-14 20:13:45

标签: join sequel ramaze

我有一个使用Ramaze和Sequel的红宝石应用程序。

我有类Tag和Tagging有这种关系:

class Tag < Sequel::Model
  one_to_many  :taggings, :class => 'Thoth::Tagging'

class Tagging < Sequel::Model(:taggings)
  many_to_one :tag, :class => 'Thoth::Tag'

我想按照受欢迎程度返回一个标签列表,即标签最多的标签(过滤任何少于三个标签的标签)。我是这样做的:

tags = .left_outer_join(:taggings, :tag_id => :id).group(:tag_id).having("count(*) > 2").order("count(*) desc").all

这确实返回了一些标签对象,但是当我在它们上面调用.id时,我得到了一个指向标签的标签的id,而不是标签本身。

仔细观察后,结果与常规查找完全不同:

> 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}>

在这两种情况下,我都会得到一个Thoth :: Tag,但根据我想要的连接中的不同字段,这些值是完全不同的。

我真正需要做的就是获得一个按标签数量排序的常规标签对象列表,但是采用有效的单一查询方式。还有更好的方法吗?

谢谢,最大

1 个答案:

答案 0 :(得分:1)

默认选择为*,因此您要从tagstaggings中选择列。如果两个表中都有id列,因为Sequel将记录作为按列名称键入的哈希值返回,taggings表中的列将覆盖tags表中具有相同名称的列

如果您只想要tags中的列,请将select_all(:tags)添加到数据集中。

Sequel master分支有一个table_select插件,默认情况下会处理这种情况。