Topic: Formatting a Name

I'd like to do something like the following

  self.first_name + " " unless self.first_name.nil?
  self.middle_name + " " unless self.middle_name.nil?
  self.last_name unless self.last_name.nil?

without having to resort to something like this

  unless !self.middle_name.nil? && !self.middle_name.nil? && !self.middle_name.nil?
    if !self.first_name.nil? && !self.last_name.nil?
      self.first_name + " " + self.last_name
    else
      if !self.last_name.nil?
        self.last_name
      end
      if !self.first_name.nil?
        self.first_name
      end
      if self.first_name.nil? && self.last_name.nil?
        return ""
      end
    end
  else
    self.first_name + " " + self.middle_name + " " + self.last_name
  end

While this DOES work, it looks horrible!  I know I'm in the Ruby forum, but this is in a Rails app.  I'm here because it's a formatting problem, not a Rails issue.  So, the problem.  The top example only spits out the last name if it is there.  If it is not, it returns nil.

How do I get it to return all three parts of the name with those conditions in place?

Thanks!

Last edited by slant (2007-06-06 13:33:12)

Re: Formatting a Name

You're going to love this. smile

[first_name, middle_name, last_name].compact.join(' ')

"compact" removes nil values from the array.

Railscasts - Free Ruby on Rails Screencasts

Re: Formatting a Name

Oh... my... gosh.  Beautiful!  And is so clean, too!

If I could bother you for a second opinion about a variance on this same thing.  I have another method called 'format_name' that does the same thing but uses only the first and last name with a comma separating them IF both exists.  If only one exists, then only that one is returned.

> "Last, First" # neither first nor last is nil
> "Last"        # first is nil
> "First"       # last is nil

Where do you go to learn these wonderful things that you know?!  I have such a hard time finding good resources other than actual books (pickaxe, prog ruby, ruby for rails, etc) since things change so much - it seems that half the 'tutorial' sites out there (save for yours, of course) is out of date!  So I don't know what to instill in my mind and what to reject.  Just curious.  Thanks so much again!

Last edited by slant (2007-06-06 14:01:06)

Re: Formatting a Name

You can accomplish this in a very similar manner.

[last_name, first_name].compact.join(', ')

slant wrote:

Where do you go to learn these wonderful things that you know?!

A number of ways:

1. reading books (AWDwR, Pickaxe, etc.)
2. reading API (for both Ruby and Rails)
3. reading blog posts
4. reading source code
5. experimenting

Railscasts - Free Ruby on Rails Screencasts

Re: Formatting a Name

Okay, I feel like a moron on that one.  Thanks.

And thanks for the feedback on my question.  I really do enjoy your screencasts.  Thanks for taking the time to do put them together.  Quality stuff!  I'm very interested in seeing some information on rjs files and ajax if you're taking requests (unless there is a better place to send that sort of thing).  By this, I refer to clicking a create button, a div slides down (instructed by new.rjs) with the "new" form view in it, once submitted, it saves and slides back up.  Just something simple like that.  My problem is knowing even the bare basics of how to even get started in this area.

Anyway, just a few thoughts.  Thanks again also for taking the time to answer the seemingly obvious questions!

Re: Formatting a Name

I'm trying to create a simple method on a client model to help me format names in different ways. The first middle and last names are already stored in the database for each client, i just want to pass the parameters to indicate which way to format. You should be able to pass up to 3 parameters to the method- :first, :middle, :last and also have the ability to tack the :initial onto each parameter to only return the initial.

Examples: I would like to be able to call the name method and pass it various parameters to format appropriately:
1. @client.name(:first, :last) and have it output "Firstname Lastname"
2. @client.name(:last, :first) and have it output "Lastname, Firstname"
3. @client.name(:first => :initial, :middle => :initial, :last) and have it output "F. M. Lastname"
4. etc.

My Ruby is seriously lacking which makes this task more difficult than I believe it needs to be. Can anyone push me in the right direction? Thanks in advance!

Last edited by jmcopeland (2007-06-18 03:19:22)

Re: Formatting a Name

The first two points have a fairly easy solution, if you modify your requirements just a little:

# in your model, of course:
def name(format)
  case format
    when :first_and_last
      [first, last].compact.join(" ")
    when :last_and_first
      [last, first].compact.join(", ")
  end
end

For your third point, that code just can't work: You are passing a hash, which does not guarantee the order (like an array does). You could make a more general method that takes a string with formatting characters that get parsed, much like Time#strftime. Then you could do something like:

@client.name("%F %L")
@client.name("%L, %F")
@client.name("%f. %m. %L")

to output the equivelant of your three points accordingly. This is possible, and I'd love to help you figure it out, but you have to consider that this will involve a fair amount of complexity. You have to weigh that against the simplicity (and reduced flexibility) of a method like above that simply takes a named format. You have to ask yourself if it is profitable to spend possibly several hours on a method to get a bit of increased flexibility. Are you going to need to format the name in so many different ways that this kind of method is warranted? The answer may very well be yes, but the exercise of thinking it through is important. Think about the interface too: The above snippet is not the prettiest code. Something like "@client.name(:short)" and "@client.name(:full)" is a lot more elegant and easier to understand a few months down the road. Choose carefully, and post back herre if you need more help.

Re: Formatting a Name

fabio wrote:

This is possible, and I'd love to help you figure it out, but you have to consider that this will involve a fair amount of complexity. You have to weigh that against the simplicity (and reduced flexibility) of a method like above that simply takes a named format. You have to ask yourself if it is profitable to spend possibly several hours on a method to get a bit of increased flexibility. Are you going to need to format the name in so many different ways that this kind of method is warranted? The answer may very well be yes, but the exercise of thinking it through is important. Think about the interface too: The above snippet is not the prettiest code. Something like "@client.name(:short)" and "@client.name(:full)" is a lot more elegant and easier to understand a few months down the road. Choose carefully, and post back herre if you need more help.

First off, thank you very much for your time and helpful answer, I really do appreciate it. You are absolutely correct that this isn't so important as to justify spending lots of time on it; however, I was approaching it more as a learning exercise than anything else. I'm still in the beginning phases of learning ruby and rails, so I truly do appreciate the help. I just thought the syntax looked pretty so I wanted to try and make it work. When it became more difficult than I thought it would be, I came here thinking I overlooked some helpful rubyism. Apparently not, hashes don't maintain order and that is that. Thanks again!

Last edited by jmcopeland (2007-06-18 15:18:00)