-1

我在 Ruby 1.9.3 上运行 Rails 3.2.10,使用 PostgreSQL 作为数据库,使用 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

为什么要打第二个电话?我怎样才能避免它?

这是猴子模型的迁移:

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

更新

我重新启动了服务器,它按照公认的答案工作。

4

1 回答 1

3

实际上,该行@monkeys = Monkey.where(user_id: 2)根本不执行 SQL 查询。它只是生成一个Relation对象:

Monkey.where(user_id: 2).class   #=> ActiveRecord::Relation < Object

只有在 Rails 需要数据时才会执行查询,例如,如果您调用.each、或在..all.first.to_sRelation

如果您将 存储Relation在一个变量中@monkey并且在您的代码中有类似的东西@monkey.where(is_active: true).first,那么将执行第二个查询,因为.where(is_active: true)除了存储在@monkey.

我很确定上面的行不会进行两个 SQL 查询。控制器、助手或视图中有一些东西会触发第二个查询。你可以在 Rails 控制台中尝试,如果你@monkeys = Monkey.where(user_id: 2)在那里输入会发生什么?什么是输出,什么是登录到你的log/development.log

于 2013-11-10T12:22:44.473 回答