I have a very concrete dilemma right now.
Given the following models:
class Message < ActiveRecord::Base
attr_accessible :body, :sent_at
belongs_to :subject
end
class Subject < ActiveRecord::Base
attr_accessible :title
has_many :messages
belongs_to :last_message, :class_name => 'Message', :foreign_key => 'last_message_id'
end
In a view I want to iterate over a list of subjects and display:
– Subject title
– sent_at for the subject’s last message
like this:
<% @subjects.each do |subject| %>
<%= subject.title %>
<%= subject.last_message.sent_at %>
<% end %>
The thing is: subject.last_message may some times be nil. In which case, the above code will throw an exception.
So: What is the best solution to this? I can see 3 possibilities, but honestly don’t know which are considered good or bad.
1) Let the view rescue it
<%= subject.last_message.sent_at rescue '' %>
2) Make a helper
def last_message_sent_at(subject)
return '' if subject.last_message.blank?
subject.last_message.sent_at
end
<%= last_message_sent_at(subject) %>
3) Make a sort of “proxy” on the Subject model
class Subject < ...
...
def last_message_sent_at
return '' if last_message.blank?
last_message.sent_at
end
end
<%= subject.last_message_sent_at %>
Which would you choose, and why? Or is there perhaps another way, which I haven’t thought about?
/ Carsten
Use
try:So, if
subject.last_messageis nil, you will get no output; else if it is not nil, it will call the methodsent_atonsubject.last_message.It is like a convenient form for your #2 idea
Documentation
As additional thought, helper is a bad choice. You ideally always want a “receiver” (in
some_class.perform(),some_classis the “receiver” i.e. it “receives” the message “perform”). I avoid Helpers unless I need to generate HTML. So, your #3 does have a receiver, but since Rails providestry, you do not need to roll your own.