Skip to content

Instantly share code, notes, and snippets.

@ybart
Created July 27, 2011 09:43
Show Gist options
  • Save ybart/1109022 to your computer and use it in GitHub Desktop.
Save ybart/1109022 to your computer and use it in GitHub Desktop.
module ActiveRecord
class Base
class << self
alias_method :old_method_missing, :method_missing
def method_missing(method_id, *arguments, &block)
if /^find_or_build_by_([_a-zA-Z]\w*)$/ =~ method_id.to_s
names = $1.split('_and_')
relation.find_or_build_by(names, *arguments)
else
old_method_missing(method_id, *arguments, &block)
end
end
def find_or_build_by(names, *arguments)
find_attributes = {}
values = arguments[0]
names.each {|k| find_attributes[k] = values[k] }
record = where(find_attributes).first
puts relation.inspect
if record
record.sanitize_for_mass_assignment(values).each {|k, v| record.send("#{k}=", v)}
else
record = relation.build(values)
relation.push(record)
end
puts relation.inspect
return record
end
end
end
end
@ybart
Copy link
Author

ybart commented Jul 27, 2011

> c = Company.new; c.employees.find_or_build_by_id(name: 'Alfred')
=> #<Employee id: nil, name: "Alfred", city: nil, company_id: nil> 
> c.employees
 => [] 
> c.employees.relation
 => [#<Employee id: nil, name: "Alfred", city: nil, company_id: nil>] 

I expect c.employees contains the newly created employee (as contained in c.employees.relation)

I believe that my problem is that my code is in class methods, where it should belong to instance methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment