3

オプションの関連付けがあるシナリオがあります。関連付けが存在する場合もあれば、存在しない場合もあります。

画面にデータを表示しようとすると問題が発生します (単純なインデックス アクションを考えてください)。

次のアプリケーション設定を検討してください。

  • プロジェクトには多くの成果物があります
  • プロジェクトには多くの展開レコードがあります (このモデルの 2 つの属性は「名前」と「説明」です)

成果物インデックス アクション内から展開レコードの関連付けを取得することに関心があります。

次のコードで動作するようになりましたが、やや醜いと思います。

@array = deliverable.try(:project).try(:deployment_record)
if @array
   @array.each do |r|
   [r.name, r.description].join(' - ')
end

これを書き直すよりエレガントな方法は何でしょうか? 私は試した

deliverable.try(:project).try(:deployment_record).each do |r|
   [r.name, r.description].join(' - ')
end

しかし、nil:NilClassエラーの未定義のメソッド「each」に遭遇し続けます。Nil オブジェクトで呼び出される .each をうまく回避する方法が見つからないようです。どうにかしてこれをもっと優雅にできるはずだと感じていますが、指を置くことはできません。

私はこれをコードベースで何度も再利用するので、コピーしてどこにでも貼り付けると、余分な 2 行が本当に私を殺します。関連付けの取得が失敗してよかったです。エラーやメッセージなしで正常に失敗したいだけです。何か案は?

4

2 に答える 2

14

メソッドを使用しto_aて、操作する配列があることを確認できます (nil空の配列が生成されます)。

@array.to_a.each do |item|
    #Whatever...
end

これは最も洗練された方法ではto_aありません - をループに追加することを覚えておく必要があります - しかし、それが有効な列挙可能であることを保証できない場合@array、そのコードがクラッシュしないようにする最も簡単な方法です。

于 2012-09-18T17:53:20.537 に答える
2

成果物では、has_many :deployment_records, through: :project次に deployment_records を要求すると、それらは空のコレクションとして返されます。

于 2012-09-10T05:19:48.613 に答える