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
I restarted the server and it works as the accepted answer suggests.
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
?