I need a method, I call it "get_or_create(item_name)". When an
Model.get_or_create(item_name) is called,
Model.find_by_name(item_name)
will be performed fist, if there is an item with the name, the item is
return, or a new item with the name will be created and returned.
Because most of the ActiveRecord models will need this method, I try
to
extend it into ActiveRecord, and put the codes into
/lib/get_or_create.rb, and require it from environment.rb.
require 'get_or_create'
class ActiveRecord::Base
include GetOrCreate
end
Only one problem left... Can anyone tell me how to write the
get_or_create.rb ?
You mean like the find_or_create_by_ dynamic finders that ActiveRecord
already has?
Fred
If you were going to write such a method yourself, you'd want to add
it to your model's class, not ActiveRecord. So inside app/models/
model.rb:
class Model < ActiveRecord::Base
...
def self.find_or_create_by_name(name)
find_by_name(name) || create(:name => name)
end
...
end
Remember that when a method definition begins with "self.", it means
you're creating a class method, not an instance method. So you're
operating within the scope of the class, and thus don't have to prefix
the find_by_name() and create() calls with "Model.", since it's
implied.
P.S. Another style of defining class methods you'll see in some
people's code:
class Model < ActiveRecord::Base
...
class << self
def find_or_create_by_name(name)
find_by_name(name) || create(:name => name)
end
end
...
end
As far as I can deduce, these two different styles are functionally
identical and merely a matter of preference.
I believe the OP wanted to add this to ActiveRecord because he wanted the same functionality for all of his models.
Peace,
Phillip
Touche. In that case, it's probably worth noting that it'd be better
if it were written as a plug-in, rather than opening up
ActiveRecord::Base directly from environment.rb.