find_or_build_by
I recently discovered that ActiveRecord has a function Object.find_or_create_by_something. Great function, it really simplified some code at my part. One problem I had with it, thought, was when I assigned a theme as a part of a habtm relationship. Here’s an example:
1 2 3 4 5 |
post = Post.new post.name = "Test Post" post.categorie << Category.find_or_create_by_name('Whatever') post.save! |
The Category ‘Whatever’ gets created before the post is saved, thus validated. When I have an invalid post, the category is created anyhow. This is OK for Admin-input, but when users can do this, it’s not great. That’s why I wrote my own solution to the problem: Category.find_or_build_by_name(‘Whatever’). Here’s the code (not yet a plugin):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
module FindOrBuildBy def self.included(base) base.extend ClassMethods class << base alias_method_chain :method_missing, :build_by end end module ClassMethods def method_missing_with_build_by(method, *args, &block) method.to_s =~ /^find_or_build_by_(.*)$/ or return method_missing_without_build_by(method, *args, &block) fields = $1.split('_') values = args.slice!(0,fields.size) options = args[-1] || {} conditions = fields.inject({}) do |hash, name| hash.merge name.to_sym => values[fields.index(name)] end options.merge! :conditions => conditions find(:first, options) || self.new(conditions) end end end ActiveRecord::Base.send :include,FindOrBuildBy |