我有一个Tag对象(id,name)和一个Tagging对象(id,tag_id,type)。我想找到所有名称都像“kevin”的标签,我可以找到一个外部Tagging对象,类型设置为“people”(类型可以设置为人或其他标记内容)。
我尝试在Rails Tag.find方法中使用复杂的SQL请求,但没有走得太远,所以我现在尝试使用Ruby的delete_if方法使用两行:
people = Tag.find(:all, :conditions => ["name like ?", "Kevin%"])
people.delete_if { |p| Tagging.find(:all, :conditions => { :tag_id => p.id, :type => "people" }).empty? }
它确实有效,但必须有一种更聪明的方法直接在数据库中执行此操作,对吧?
感谢您的帮助,
凯文
答案 0 :(得分:1)
有几种方法可以改进。
最简单的改进是执行“SELECT count(*)”而不是为那些Taggings加载ActiveRecords。
people = Tag.all(:conditions => ["name LIKE ?", "Kevin%"])
people.delete_if { |p| Tagging.count(:conditions => { :tag_id => p.id, :type => "people" }) > 0 }
但是整个事情也可以在带有子查询的SQL中完成:
people = Tag.all(:conditions => [
"name LIKE ? AND id IN (SELECT tag_id FROM people WHERE type=?)",
"Kevin%",
"people",
])
答案 1 :(得分:1)
试试这个:
Tag.all(:joins => :taggings, :group => :id,
:conditions => ["tags.name LIKE ? AND taggings.type = ?",
"Kevin%", "person"]
)
返回以Kevin开头的标签为type =“person”。
注意:需要使用group
选项来消除重复项。