0

What is the best way to ensure that a model exists before doing string interpolation? I have a variable user, and I need to see what the user's major is. A table in between named user_attributes has the user's info.

#{user.user_attribute.major.name}

The user may not have specified a major yet, in which case they wouldn't have a major model instance yet. So when I try and get the name of the major, I would get an "undefined method on nil class type" error. Any advice on how to safely do this?

sawa
  • 165,429
  • 45
  • 277
  • 381
ajk4550
  • 743
  • 2
  • 11
  • 25
  • 1
    [Demeter: It’s not just a good idea. It’s the law.](http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/) – Stefan May 12 '16 at 15:20

4 Answers4

4

You could avoid try and add a method to your model or decorator..

def major_name
  user_attribute.major && user_attribute.major.name
end

OR

def major_name
  user_attribute.major.name if user_attribute.major?
end

Check: https://codereview.stackexchange.com/questions/28610/handling-nil-trying-to-avoid-try

Community
  • 1
  • 1
Damien Roche
  • 13,189
  • 18
  • 68
  • 96
  • 1
    Thanks! This is the answer I went with. I like the idea of doing the logic in the model instead of the view so thanks! – ajk4550 May 12 '16 at 15:06
3

You can use try method:

# if model is present
{user.user_attribute.major.try(:name)} # => "<MAJOR_NAME>"

# if model is NOT present
{user.user_attribute.major.try(:name)} # => ""

You can read more about try.

RAJ
  • 9,697
  • 1
  • 33
  • 63
2

You could use the lonely operator. It is like try, but slightly less functional (which doesn't matter in your case).

user.user_attribute.major&.name
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
0

This might well be the 'worst' answer to ruby puritans, but it works for me in some scenarios:

"#{user.user_attribute.major.name rescue nil}"
Anand
  • 3,690
  • 4
  • 33
  • 64
  • It's not about being a ruby puritan or not, it's simply not good solution. – Leonel Galán May 12 '16 at 15:36
  • @Leito - why is it not a good solution? If all I want is the string if present, or a blank string if major is not present, then this is a reasonable solution. In my scenario, I construct a complex string by interpolating various model methods, some of which may not be present. I use this and it works. – Anand May 12 '16 at 15:39
  • Is a misuse of exceptions (exceptional nature). You shouldn't expect one or use it as a conditional. There is also a performance hit, see http://stackoverflow.com/a/15397057/637094 for more details. I'm not arguing it works, I know it does and it's a solution, but simply not a good one. – Leonel Galán May 12 '16 at 15:44
  • 1
    Actually, I think it is the only good solution if we want to show something when the data not found (like "Unknown"), but correct me if I am wrong. – István Ujj-Mészáros Jan 17 '20 at 01:10