2011-08-13 19 views
2

深くネストされた関連を持つレガシーレールアプリケーションを開発しています。深くネストされた属性のいくつかをバブリングして表示する必要があります。私は(ActiveRecordのアソシエーションとアレイを使用して)結果を表示するには、このような何かをやっている時点では深くネストされたオブジェクトモデルのnilsを扱うためのテクニック

model_a 
    .collection_of_model_b 
    .map(&:collection_model_c) 
    .flatten 
    .map(&:collection_model_d) 
    .display_field 

このアプローチでは、テストデータで働いていたが、私は、実際のデータを使用して開始したら、私はすべての上NilClassエラーを気づき始めました場所。

このデータを取得するために使用できる手法、構文、パターンについてガイダンスを提供してください。

私が考えているがまだ追求していないアプローチ: 1)レベルを下がるたびにnilsのチェックを行う別々の行でコールを分割します。 2)ストレートSQL(find_by_sql)を使用してください。

+0

'.reject'はnil値をフィルタリングする可能性がありますか? – Mchl

+0

どのステップが無限オブジェクトを導入していますか? – tokland

+0

ステップは、私が選んだmodel_aに基づいて変化します。場合によっては、Arrayでnilになるmodel_bオブジェクトであり、それ以外の場合はmodel_cまたはmodel_dです。以下で述べるように、私はnilsに対して保護するために、あらゆる場合にmapを呼び出す前にコンパクトに実行しようとします。 – RidingRails

答えて

2

使用Array#compact:団体を通じて:

>> [1, 2, nil, 3].compact 
=> [1, 2, 3] 

>> [[1, 2], [3, nil], [4]].map(&:compact) 
=> [[1, 2], [3], [4]] 
+0

はい、私はアソシエーションの各呼び出しの前に実行するつもりです。他に提案がある場合はお知らせください。 – RidingRails

0

ごhas_mayを持っていますか?個人的に

class ModelA < ActiveRecord::Base 
    ... 
    has_many :model_bs 
    has_many :model_cs, :through => :model_bs 
    has_many :model_ds, :through => :model_cs 
    ... 
end 

のような、私はMODELAはまだモデルのB & Cのメンバーについて多くのことを知っている。しかし、これは、少なくともそれを離れて抽象化し、今あなただけ呼び出すことができ、これはまだ、デメテルの法則に違反すると思う:

model_a.model_ds.map(&:display_field) 
関連する問題