I spent some time figuring this out and haven't seen others post on it so maybe this will help someone. Also, I don't have much Rails experience so I'd be grateful for any corrections or suggestions, though the code below seems to work well.
I've set up a virtual attribute to make full_name out of first_name and last_name as discussed in the Railscast on virtual attributes . I wanted to search by full_name as well so I added a named_scope as suggested in Jim's answer here.
named_scope :find_by_full_name, lambda {|full_name|
{:conditions => {:first => full_name.split(' ').first,
:last => full_name.split(' ').last}}
}
BUT... I wanted to be able to use all of this as :find_or_create_by_full_name. Creating a named scope with that name only provides searching (it's identical to the :find_by_full_name code above) -- i.e. it doesn't do what I want. So in order to handle this I created a class method for my User class called :find_or_create_by_full_name
# This gives us find_or_create_by functionality for the full_name virtual attribute.
# I put this in my user.rb class.
def self.find_or_create_by_full_name(name)
if found = self.find_by_full_name(name).first # Because we're using named scope we get back an array
return found
else
created = se开发者_如何学运维lf.find_by_full_name(name).create
return created
end
end
You could as well just Use
User.find_or_create_by_first_name_and_last_name(:first_name => "firstname", :last_name => "last_name")
精彩评论