Skip to content

Instantly share code, notes, and snippets.

@baroquebobcat
Created January 10, 2012 03:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baroquebobcat/1586708 to your computer and use it in GitHub Desktop.
Save baroquebobcat/1586708 to your computer and use it in GitHub Desktop.
get hashes working w/ association find_or_create in rails 2.3.x > 2.3.8
--- !map:HashWithIndifferentAccess
body: other test comment body
type: test
module ActiveRecord
module Associations
class AssociationCollection < AssociationProxy
def method_missing(method, *args, &block)
case method.to_s
when 'find_or_create'
return find(:first, :conditions => args.first) || create(args.first)
when /^find_or_create_by_(.*)$/
rest = $1
find_args = pull_finder_args_from(DynamicFinderMatch.match(method).attribute_names, *args)
return send("find_by_#{rest}", *find_args) ||
method_missing("create_by_#{rest}", *args, &block)
when /^create_by_(.*)$/
attribute_names = $1.split('_and_')
if args[0].is_a? Hash
create_args = args[0]
else
create_args = Hash[ attribute_names.zip(args.first(attribute_names.length))]
if args.length > attribute_names.length && args[attribute_names.length].is_a?(Hash)
create_args.merge! args[attribute_names.length]
end
end
return create create_args, &block
end
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
if block_given?
super { |*block_args| yield(*block_args) }
else
super
end
elsif @reflection.klass.scopes.include?(method)
@reflection.klass.scopes[method].call(self, *args)
else
with_scope(construct_scope) do
if block_given?
@reflection.klass.send(method, *args) { |*block_args| yield(*block_args) }
else
@reflection.klass.send(method, *args)
end
end
end
end
end
end
end
other_comment = post.comments.find_or_create_by_body(:body => 'other test comment body', :type => 'test')
other_comment.body
# => {:body => 'other test comment body', :type => 'test'}
other_comment = post.comments.find_or_create_by_body('other test comment body') do |comment|
comment.type = 'test'
end
other_comment.body
# => "other test comment body"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment