1

So I have the following code that I wanted to make a little more readable:

user = User.find_by_username(username)
user = User.new(credentials) if user.nil?

Essentially the first line is the default, the following line instantiates itself if it's not already set.

Is there a way I can clean this up a bit and get it onto a single line of code? Something like this maybe:

user = User.find_by_username(username) || User.new(credentials)

Edit

I now realize the the code I provided does exactly what I need, sorry for wasting cyberspace but feel free to suggest alternative solutions.

Noz
  • 6,216
  • 3
  • 47
  • 82

2 Answers2

5

Yes, what you wrote is exactly the correct answer.

You could also write it this way, if preferred:

user = User.find_by_username(username)
user ||= User.new(credentials)

Keep in mind that your first example will only assign the second value if the first one is nil, but your second example and my example above will assign the second value on both nil and false.

EDIT: As mentioned by others, if you're working with Active Record you could also use a dynamic attribute-based finder

user.find_or_initialize_by_username(credentials)
Grant Hutchins
  • 4,275
  • 1
  • 27
  • 32
3

its easier to do

user.find_or_create_by_name(credentials)

and credentials will have username there

see Rails find_or_create by more than one attribute?

and http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Community
  • 1
  • 1
Nick Ginanto
  • 31,090
  • 47
  • 134
  • 244
  • Good thinking, but in this case I'm not looking to commit the object right off the hop. – Noz Oct 12 '12 at 22:23
  • 1
    Then you could use user.find_or_initialize_by_username(credentials)... see http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Dynamic+attribute-based+finders – Grant Hutchins Oct 13 '12 at 18:12