Reputation: 420
Recently I moved from C# to ruby on rails and checking records in rails console, in which i accidently made typo mistake. Instead of using find() I used find{}
. It is working but it always returns first record from table. I don't know how this happened.
When i googled this I found out that it has something to do with block but i didn't get any idea.
I typed Book.find{3} instead of Book.find(3)
Upvotes: 2
Views: 72
Reputation: 33420
It's because when you pass a block to find
it returns super
:
def find(*ids) # :nodoc:
# We don't have cache keys for this stuff yet
return super unless ids.length == 1
return super if block_given? ||
primary_key.nil? ...
...
end
Which then invokes find
again, without a block and evaluating all other conditions as false:
return super unless ids.length == 1
return super if block_given? ||
primary_key.nil? ||
scope_attributes? ||
columns_hash.key?(inheritance_column) && !base_class?
Allowing it to make a query to itself (the model, Book e.g) with a limit of 1:
...
statement = cached_find_by_statement(key) { |params|
where(key => params.bind).limit(1)
}
...
Taking then the first element from the object statement, which is an ActiveRecord::StatementCache, similar to an ActiveRecord::Relationship object, holding 1 or more objects belonging to a model (Book in this case):
record = statement.execute([id], connection)&.first
Hence if statements
is evaluated as truthy it is returned otherwise a RecordNotFound exception is raised:
record = statement.execute([id], connection)&.first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id)
end
record
You can see this here.
Upvotes: 2