0

私は今、非常に具体的なジレンマを抱えています。

次のモデルが与えられます:

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

ビューでは、サブジェクトのリストを繰り返して表示したいと思います。-サブジェクトタイトル-次のようなサブジェクトの最後のメッセージのsent_at:

<% @subjects.each do |subject| %>
  <%= subject.title %>
  <%= subject.last_message.sent_at %>
<% end %>

重要なのは、subject.last_messageがnilになる場合があるということです。その場合、上記のコードは例外をスローします。

だから:これに対する最良の解決策は何ですか?私は3つの可能性を見ることができますが、正直なところ、どちらが良いか悪いかはわかりません。

1)ビューにそれを救出させます

<%= subject.last_message.sent_at rescue '' %>

2)ヘルパーを作る

def last_message_sent_at(subject)
  return '' if subject.last_message.blank?
  subject.last_message.sent_at
end

<%= last_message_sent_at(subject) %>

3)サブジェクトモデルで一種の「プロキシ」を作成します

class Subject < ...
  ...
  def last_message_sent_at
    return '' if last_message.blank?
    last_message.sent_at
  end
end

<%= subject.last_message_sent_at %>

どちらを選びますか、そしてその理由は何ですか?それとも、私が考えていなかった別の方法がありますか?

/カルステン

4

3 に答える 3

2

使用try

<%= subject.last_message.try(:sent_at) %>

したがって、subject.last_messageがnilの場合、出力は得られません。それ以外の場合、nilでない場合は、のメソッドを呼び出しsent_atますsubject.last_message

それはあなたの#2のアイデアのための便利なフォームのようなものです

ドキュメンテーション

追加の考えとして、ヘルパーは悪い選択です。理想的には、常に「レシーバー」が必要です(つまりsome_class.perform()some_class「レシーバー」、つまり「実行」メッセージを「受信」します)。HTMLを生成する必要がない限り、ヘルパーは避けます。つまり、#3にはレシーバーがありますが、Railsが提供するのでtry、自分でロールする必要はありません。

于 2012-09-15T08:50:30.603 に答える
0

この場合の最も簡単な方法は、単にnull値をチェックすることです...

<% @subjects.each do |subject| %>
  <%= subject.title %>
  <%= subject.last_message.sent_at if subject.last_message %>
<% end %>

また

<% @subjects.each do |subject| %>
  <%= subject.title %>
  <%= subject.last_message && subject.last_message.sent_at %>
<% end %>
于 2012-09-15T08:59:30.347 に答える
0

実行するロジックまたはアクションがある場合、ベストプラクティスは、それをビューから(ヘルパー、プレゼンターに)移動することです。

あなたの質問は「おそらくnilインスタンスでメソッドを呼び出す方法」に関するものなのでtry、この場合はおそらく最良の方法です。なぜなら、それはすでにそこにあり、余分なものは必要ないからですgem

一方、render @subjectsブロックコンテンツを_subjectパーシャルに配置して移動するだけで、コードを改善できます。Railsがループを行います。

于 2012-09-15T12:01:38.567 に答える