在Rails(3.2)应用程序中,我在模型上有一个类方法:
def import(level, max = 10)
db = ActiveRecord::Base.connection
result = db.execute("SELECT word FROM levels WHERE level == #{level} AND word NOT IN (SELECT entry FROM words) limit #{max};");
它一次只导入10个新单词(创建10个记录),但尚未作为Word记录存在。
架构看起来像这样:
create_table "levels", :force => true do |t|
t.string "word"
t.integer "level"
end
create_table "words", :force => true do |t|
t.string "entry"
t.integer "level", :default => 0
t.text "definition"
t.string "thesaurus", :default => "none"
end
我是一个SQL菜鸟。使用rails dbconsole(sqlite3,我在服务器上也使用sqlite3),我以某种方式想出了上面的原始sql查询。我知道我可以用Arel做同样的事情。我应该如何用ActiveRecord构造查询?
答案 0 :(得分:1)
以下(未经测试)应该有效。它在子查询中使用pluck。
Level.where(:level => level).where("word NOT IN (?)", Word.pluck(:entry)).limit(max)
答案 1 :(得分:0)
@ Gazler的解决方案看起来很有效,但我会提供一种使用MetaWhere
语法的替代方法,它更简洁:
Level.where(:level => level, :word.not_in => Word.pluck(:entry)).limit(max)