Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there find_or_create_by_ that takes a hash in Rails?

Here's some of my production code (I had to force line breaks):

task = Task.find_or_create_by_username_and_timestamp_and_des \
cription_and_driver_spec_and_driver_spec_origin(username,tim \
estamp,description,driver_spec,driver_spec_origin)

Yes, I'm trying to find or create a unique ActiveRecord::Base object. But in current form it's very ugly. Instead, I'd like to use something like this:

task = Task.SOME_METHOD :username => username, :timestamp => timestamp ...

I know about find_by_something key=>value, but it's not an option here. I need all values to be unique. Is there a method that'll do the same as find_or_create_by, but take a hash as an input? Or something else with similat semantics?

like image 973
P Shved Avatar asked Oct 01 '10 17:10

P Shved


1 Answers

Rails 3.2 first introduced first_or_create to ActiveRecord. Not only does it have the requested functionality, but it also fits in the rest of the ActiveRecord relations:

Task.where(attributes).first_or_create

In Rails 3.0 and 3.1:

Task.where(attributes).first || Task.create(attributes)

In Rails 2.1 - 2.3:

Task.first(:conditions => attributes) || Task.create(attributes)

In the older versions, you could always write a method called find_or_create to encapsulate this if you'd like. Definitely done it myself in the past:

class Task
  def self.find_or_create(attributes)
    # add one of the implementations above
  end
end
like image 125
wuputah Avatar answered Sep 21 '22 06:09

wuputah