如何将此原始SQL转换为Arel查询?

时间:2012-04-16 09:35:54

标签: sql ruby-on-rails activerecord arel

在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构造查询?

2 个答案:

答案 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)