[LRUG] Baffled by inconsistent behaviour of Rails find_by_* method
Graham Ashton
graham at effectif.com
Wed Aug 24 04:42:04 PDT 2011
On 24 Aug 2011, at 12:09, Mark Woods wrote:
>> There are indeed those three different specification codes in the database,
>> and each of them begins with "4400", but why does the same method find only
>> one when run from the console?
>
> I'm scared... is Exammodule.find_all_by_specificationcode really
> finding partial matches when given a string argument? If so, what
> query is activerecord generating?
If memory serves it was ActiveRecord 2.2.2? Even though it seems as though MySQL is at fault, I couldn't resist having a look.
If you want to follow what it's doing in this scenario:
- `finder` is :all
- `attribute_names` is ['specificationcode']
- `bang` is nil
Lines 1780-1800 of lib/active_record/base.rb (extracted from a 60 line method). The first time you call it, it generates a method on the model on the fly.
finder = match.finder
bang = match.bang?
self.class_eval %{
def self.#{method_id}(*args)
options = args.extract_options!
attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
finder_options = { :conditions => attributes }
validate_find_options(options)
set_readonly_option!(options)
#{'result = ' if bang}if options[:conditions]
with_scope(:find => finder_options) do
find(:#{finder}, options)
end
else
find(:#{finder}, options.merge(finder_options))
end
#{'result || raise(RecordNotFound)' if bang}
end
}, __FILE__, __LINE__
send(method_id, *arguments)
I can't say I'm a fan of meta programming in Ruby by lobbing strings of code around. Good to know what's behind the scenes though.
More information about the Chat
mailing list