Railsガイドを眺めていたら、render
メソッドにcollectionを渡す場合に置いて以下のような興味深い記述があった。
使用するパーシャル名は、コレクション内のモデル名に基いて決定されます。実は、メンバが一様でない (さまざまな種類のメンバが入り混じった) コレクションにも上の方法を使用できます。この場合、コレクションのメンバに応じて適切なパーシャルが自動的に選択されます。
つまり、複数のモデルが混在したメンバに対して、以下の様にrenderメソッドを呼び出すことで、
それぞれのモデルに対応したパーシャルが自動的に選択されてレンダリングされるという事。
render @contents
たとえばQiitaのフィードの様な物を想定したとする。
サイト内の様々なユーザーが取るアクティビティを、Feedモデルに対応したfeedsテーブルに格納し、
それぞれのアクションに対応するモデルをFeedモデル継承させた(単一テーブル継承)させたモデルとして作成し、
class Feed < ActiveRecord::Base
# 何らかの実装
end
class FeedPost < Feed
# 何らかの実装
end
class FeedStock < Feed
# 何らかの実装
end
それぞれ、app/views/feed_posts/_feed_post.html.erb
, app/views/feed_stocks/_feed_stock.html.erb
という、モデルに対応したパーシャルを作成しておき、controllerでおもむろにFeedモデルからデータを取得して、
class FeedsController < ApplicationController
def index
@feeds = Feed.all
end
end
アクションに対応するViewテンプレートで、以下の様にrenderメソッドを呼び出すと、
感動的な事に、事前に用意したFeedPost, FeedStockのモデルに対応したパーシャルが呼ばれる。
# app/views/feeds/index.html.erb
<%= render @feeds %>
強い。
Railsの単一テーブル継承つかった場合、親モデルからActiveRecordのメソッド(where
等)をつかってオブジェクトを取得すると、
以下のようにFeed
モデルを継承したサブクラス(FeedPost
, FeedStock
)としてオブジェクトを取得することが出来るので、renderメソッドとの相性が非常に良い事がわかった。
> Feed.all
=> #<ActiveRecord::Relation [#<FeedPost id: 1, user_id: 1, content_id: 1, created_at: "2016-11-17 03:20:56", updated_at: "2016-11-17 03:20:56">,
#<FeedStock id: 2, user_id: 1, content_id: 1, created_at: "2016-11-17 04:25:21", updated_at: "2016-11-17 04:25:21">]>