1

次の関係を仮定します。

Bloghas_many Postshas_many Commentshas_oneAuthor

Blogsallですべてを取得したい場合は、次のPostsように記述できます。

Blog.all.as_json(:include => :posts)

ただし、これは N+1 クエリになります。

したがって、代わりに次のように書く必要があります。

Blog.includes(:posts).all.as_json(:include => :posts)

これは期待どおりに機能しますが、特にネストされたインクルードがある場合は、あまり DRY ではありません。

例えば:

Blog.includes(
    :posts => {
        :comments => :author
    }
).all.as_json(
    :include => {
        :posts => {
            :include => {
                :comments => {
                    :include => :author
                }
            }
        }
    }
)

複数の場所で同じ JSON 形式を照会する必要がある場合、この問題はさらに悪化します。

as_json次のように、リレーション形式をクラス メソッドに入れることを考えました。

class Blog < ActiveRecord::base
...
  def self.include_all_json_format
    :include => {
        :posts => {
            :include => {
                :comments => {
                    :include => :author
                }
            }
        }
     }
   end
...
end

これにより、複数の場所でこの JSON 形式をクエリする問題が解決されます。

Blog.includes(
    :posts => {
        :comments => :author
    }
).all.as_json(
    Blog.include_all_json_format
)

しかしもちろん、Blog.includes()はリレーション ハッシュに別の形式をとるので、次のようになります。

Blog.includes(
    Blog.include_all_json_format
).all.as_json(
    Blog.include_all_json_format
)

うまくいきません。

Blog.includes()リレーションシップ ハッシュを 2 番目のクラス メソッドに入れることもできますが、2 つのメソッドで同じ include 構造を宣言するのは DRY ではありません。


私が今考えることができる唯一のアイデアは、Blog.include_all_json_format上記の方法を使用し、そのリレーションハッシュを(本質的にはキーBlog.includes()を取り除くだけで)期待される形式に変換できるコンバーターメソッドを作成して、次のように呼び出すことです。:include

Blog.includes(
    MyConverter(Blog.include_all_json_format)
).all.as_json(
    Blog.include_all_json_format
)

:onlyしかし、:except自分のフォーマットで使用したい場合は複雑になりas_jsonます。


これらのインクルードを DRY するにはどうすればよいですか?

おそらく、名前付きスコープまたはいくつかの宝石を利用する方法はありますか?

どんな助けでも大歓迎です。

4

1 に答える 1

0

as_jsonモデルのメソッドをオーバーライドできます

例えば

class Blog < ActiveRecord::Base

  def as_json
    super(:include => :posts)
  end
end

次に、コントローラーは次のようになります

render json: @blogs

提案

JBuilder、Rabl、AMS、またはその他のテンプレート ライブラリを使用して、コントローラー/モデル ロジックから応答構築を分離することができます。これを行うと、間違いなくコードが枯渇します。

于 2013-03-09T20:10:50.643 に答える