LoginSignup
5
4

More than 5 years have passed since last update.

複数のモデルが入り混じったメンバに対してrenderメソッドを使うと、各モデルに適切なパーシャルを読んでくれる

Last updated at Posted at 2016-11-17

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">]>
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4