Jonas Grau Jonas Grau - 6 months ago 27
Ruby Question

Best way to find_or_create_by_id but update the attributes if the record is found

I'm looking for a clean way to create a record with a set of attributes if the record does not exist and - if the record do exist - to update its attributes. I love the syntax of the block in the find_or_create_by_id call. Here's my code:

@categories = Highrise::DealCategory.find(:all)

@categories.each do |category|
puts "Category: #{}"

Category.find_or_create_by_id( do |c| =

The problem here is that if the record exists but the name has changed, it is not being updated.

Looking for a clean solution to this problem...


You can write your own method:

class ActiveRecord::Base
  def self.find_by_id_or_create(id, &block)
    obj = self.find_by_id( id ) ||
    yield obj


 Category.find_by_id_or_create(10) do |c| = "My new name"

Of course, in this way you should extend method missing method and implement this method in the same way as others find_by_something methods. But for being short this will be enough.