Nooby Help with created_at, updated_at, and if/then

Some might debate this, but I find the best way is to factor the
whole thing into a helper or a model. E.g.:

# my model.rb

def timestamp_string    updated_at > created_at ?      "Updated by #{author} at #{updated_at.to_formatted_s(:short)}" :      "Created by #{author} at #{created_at.to_formatted_s(:short)}" : end

# my view.rhtml

<%= post.timestamp_string %>

This should clean up your view. If you feel this couples your model
too tightly with the display of the data, then create a helper instead.

Does this help?

def timestamp_string    updated_at > created_at ?      "Updated by #{author} at #{updated_at.to_formatted_s(:short)}" :      "Created by #{author} at #{created_at.to_formatted_s(:short)}" : end

I've not seen the one-line if-then-else statement form like:    <condition> ? <action_to_do_if_true> : <action_to_do_if_false>

expanded into MORE than one line. I just tried it in irb. It works -- SORT OF -- but it's hard to follow. These both work:

true ? 1 : 2

true ? 1 : 2

... generating an output of "1". But you can't leave anything out. So these generate an error:

true ? 1

true ? 1

.. as do:

true ? 1 :

true ? 1 :

Besides, as Ben notes, they're not clear. So indeed, do it the easy way:   def timestamp_string       if updated_at > created_at         "Updated by #{author} at #{updated_at.to_formatted_s(:short)}"         "Created by #{author} at #{created_at.to_formatted_s(:short)}"       else         "Created by #{author} at #{created_at.to_formatted_s(:short)}"       end   end

But this won't work either, because methods return only the LAST assignment statement, unless you include an explicit "return <expression>". So regardless of the values of updated_at and created_at, the above would return ONLY the line starting with "Created by". (Try it in irb.)

Let's try again, eliminating the duplicate assignment while we're at it. I added an end-of-line character so the strings wouldn't just run together. And because you can't use the "+=" method unless a variable has been initialized as a string, number, array, or something similar, you wind up with something like:

  def timestamp_string       s = ""       if updated_at > created_at         s = "Updated by #{author} at #{updated_at.to_formatted_s(:short)}\n"       end       s += "Created by #{author} at #{created_at.to_formatted_s(:short)}"   end

If you REALLY wanted, you could shorten this to:

  def timestamp_string       updated_at > created_at ? s = "Updated by #{author} at #{updated_at.to_formatted_s(:short)}\n" : s = ""       s += "Created by #{author} at #{created_at.to_formatted_s(:short)}"   end

---Jim Gagne---

Did I inadvertently stick a colon at the end of that? Oops. The
ternary operator, ?, is equivalent to an if/else. So:

updated_at > created_at ? stmt_a : stmt_b

is equivalent to:

if updated_at > created_at    stmt_a else    stmt_b end

It all depends on what you're used to.

That’s why I used the ternary operator. It seems obvious to me that the last evaluation will depend on the result of the conditional.

irb(main):001:0> a = 1

=> 1

irb(main):002:0> b = 2

=> 2

irb(main):003:0> a > b ? ‘a is greater than b’ : ‘a is not greater than b’

=> “a is not greater than b”

irb(main):004:0> a = 2

=> 2

irb(main):005:0> b = 1

=> 1

irb(main):006:0> a > b ? ‘a is greater than b’ : ‘a is not greater than b’

=> “a is greater than b”

irb(main):007:0>

Thanks Everyone. Very Helpful :slight_smile: