简体   繁体   中英

How to chain try() and scoped to_s() in Rails?

In a Rails view, one can use try to output only if there is a value in the database, eg

@model.try(:date)

And one can chain trys if, for example, the output is needed as a string

@model.try(:date).try(:to_s)

But what if I need to call a scoped format? I've tried

@model.try(:date).try(:to_s(:long))
@model.try(:date).try(:to_s).try(:long)

What is the correct syntax for this? And what is a good reference for more explanation?

Thanks

From the fine manual :

try(*a, &b)
[...]
try also accepts arguments and/or a block, for the method it is trying

 Person.try(:find, 1) 

So I think you want:

@model.try(:date).try(:to_s, :long)

This one won't work:

@model.try(:date).try(:to_s(:long))

because you're trying to access the :to_s symbol as a method ( :to_s(:long) ). This one won't work:

@model.try(:date).try(:to_s).try(:long)

because you're trying to call the long method on what to_s returns and you probably don't have a String#long method defined.

mu is too short's answer shows the correct usage for the try method with parameters:

@model.try(:date).try(:to_s, :long)

However, if you are using Ruby 2.3 or later, you should stop using try and give the safe navigation operator a try (no pun intended):

@model&.date&.to_s(:long)

The following answer is here for historical purposes – adding a rescue nil to the end of statements is considered bad practice, since it suppresses all exceptions:

For long chains that can fail, I'd rather use:

 @model.date.to_s(:long) rescue nil 

Instead of filling up my view with try(...) calls.

Also, try to use I18n.localize for date formatting, like this:

 l @model.date, format: :long rescue nil 

See: http://rails-bestpractices.com/posts/42-use-i18n-localize-for-date-time-formating

In case you often use try chains without blocks, an option is to extend the Object class:

class Object
  def try_chain(*args) 
    args.inject(self) do |result, method| 
      result.try(method)
    end
  end
end

And then simply use @model.try_chain(:date, :to_s)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM