我在Ruby 1.9.3上运行Rails 3.2.10,使用PostgreSQL作为db和RubyMine来调试我的代码。在调试时,我注意到了这一行:
@monkeys = Monkey.where(user_id: 2)
进行2次数据库调用并生成以下日志:
Monkey Load (0.6ms) SELECT "monkeys".* FROM "monkeys" WHERE "monkeys"."user_id" = 2
Monkey Load (1.4ms) SELECT "monkeys".* FROM "monkeys" WHERE "monkeys"."user_id" = 2 AND "monkeys"."is_active" = 't' LIMIT 1
为什么第二次通话?我怎么能避免它?
这是Monkey Model的迁移:
class CreateMonkeys < ActiveRecord::Migration
def change
create_table :monkeys do |t|
t.belongs_to :user, null: false
t.belongs_to :monkey_template, null: false
t.boolean :is_redeemed, null: false, default: false
t.boolean :is_active, null: false, default: true
t.datetime :activation_time
t.datetime :expiration_time
t.datetime :redemption_time
t.timestamps
end
add_index :monkeys, :user_id
end
end
我重新启动了服务器,它就像接受的答案所说的那样有效。
答案 0 :(得分:3)
实际上,行@monkeys = Monkey.where(user_id: 2)
根本不执行SQL查询。它只生成一个Relation
对象:
Monkey.where(user_id: 2).class #=> ActiveRecord::Relation < Object
只有在Rails需要数据时才会执行查询,例如,如果您在.each
上调用.all
,.first
,.to_s
或Relation
。
如果您将Relation
存储在变量@monkey
中,并且代码中的@monkey.where(is_active: true).first
类似于执行第二次查询,那么.where(is_active: true)
部分会定义另一个关系除了@monkey
中存储的那个。
我很确定上面的行不会产生两个SQL查询。控制器,帮助器或视图中有一些触发第二个查询的内容。您可以在Rails控制台中尝试,如果在那里键入@monkeys = Monkey.where(user_id: 2)
会发生什么?什么是输出,登录到您的log/development.log
?