-1

I am running Rails 3.2.10 on Ruby 1.9.3, use PostgreSQL as the db and RubyMine to debug my code. While debugging, I noticed that, this line:

@monkeys = Monkey.where(user_id: 2)

Makes 2 database calls and generates the following logs:

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

Why the second call? How can I avoid it?

This is the migration for the 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

UPDATE

I restarted the server and it works as the accepted answer suggests.

boomslang
  • 118
  • 1
  • 1
  • 6
  • 1
    Do you have a default_scope defined somewhere ? Do you issue any `exist?` or `any?` or `first` query after that ? We need more context (controller code, view code, models...) – m_x Nov 10 '13 at 11:57
  • Peronally, I wouldn't worry about that. The great thing with SQL is that you don't have to worry about how it is implemented. – wvdz Nov 10 '13 at 11:58
  • Could you also paste the code of the model? – KARASZI István Nov 10 '13 at 12:09

1 Answers1

3

Actually the line @monkeys = Monkey.where(user_id: 2) does not do a SQL query at all. It just generates a Relation object:

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

The query is only performed if Rails needs the data, for example if you call .each, .all, .first or .to_s on the Relation.

If you store the Relation in a variable @monkey and have something like @monkey.where(is_active: true).first in your code than a second query is performed, because the .where(is_active: true) part defines another Relation in addition to the one that was stored in @monkey.

I am pretty sure the line above will not make two SQL queries. There is something in the controller, helpers or views that trigger the second query. You can try that in your Rails console, what happens if you type @monkeys = Monkey.where(user_id: 2) in there? What is the output, what is logged into your log/development.log?

Jon
  • 10,678
  • 2
  • 36
  • 48
spickermann
  • 100,941
  • 9
  • 101
  • 131