Railsの親/子をフロントエンドJSに送信して、ネストされたオブジェクトとしてアクセスできるようにする方法
概要
バックエンドでは、私のオブジェクトの関係は、項目に多数のオプションがあるということです。フロントエンドでアイテムのすべての属性とその子オプションにハッシュとしてアクセスできるようにしたいと考えています。
items = [
{
id: 1,
item_attribute_name: item_attribute_value,
options: [
{id: 1, option_attribute_name: option_attribute_value},
{id: 2, option_attribute_name: option_attribute_value},
]
},
{
id: 2,
item_attribute_name: item_attribute_value,
options: []
}
]
私は、ajax リクエストに応じて json オブジェクトを介して、または便利な gon gem を使用してデータを送信しています。親アイテムを送信したいだけであれば、Item.all を送り返すだけでフォーマットが自動的に行われ、フロントエンドで各アイテムがその属性を正確に表すハッシュであるアイテムの配列を取得できることに気付きました。私が望むように。
しかし、子供たちを送りたい場合、標準的な方法はあるのでしょうか?以下のように子属性を自分で構築できることはわかりましたが、より直接的な方法があるかどうか疑問に思っています。
子属性を構築してこれを機能させる方法は次のとおりです。
items = Item.all
items.each do |i|
child_attr = {"options" => i.options }
i.attributes.merge(child_attr)
end
ちなみに、完全に受け入れられる答えは、私が今やっていること、つまりバックエンドで各親オブジェクトを属性に変換し、子属性をつなぎ合わせること以外に、これを自動的に行う魔法の方法は存在しないということです。
率直に言って、私がこの質問をしているのは、可能であれば、オブジェクトの関係をバックエンドに保持して、ハッシュに変換するのではなく、他の場所で再利用できるとよいからです。
解決策
期待どおりの結果を得る唯一の方法は、モンキーパッチを適用することだと思います。したがって、シリアライザーを使用するか、モデルにデフォルトで含まれる ActiveModel::Serializers::JSON を含めるか、使用することができます。
たとえば、ActiveModel::Serializers::JSON を使用すると、次のようなことができます。
items = Item.all
items.map! do |i|
i.serializable_hash(include: { options: {} })
end
これは、Rails Eerage Loading によるもので、関連付け (has_many など) からすべての子をロードする必要がなくなります。どこでシリアル化するかはユースケースによって異なります。