Help us understand the problem. What is going on with this article?

Skinny Controller, Fat Modelの簡単な例

More than 5 years have passed since last update.

某所で初心者向けRailsコースを受け持っているので、生徒さん向けのメモを書き置きします。

  • 簡単なブログアプリ
    • モデルはPostAuthorのみ
  • app/views/posts/index.erbに、最新記事を5件表示させることが課題

Skinny Controller, Fat Modelとは(ざっくり)

  • 薄いコントローラー、厚いモデル
  • データ加工処理はモデルに担当させる
  • コントローラーをシンプルにする
    • 処理の流れがわかりやすくなる

Viewのみで最新記事表示を実装した場合

  • 一番原始的なパターンです。

実装方法

app/controllers/posts_controller.rb
def index
  @posts = Post.all
end
app/views/posts/index.erb
<% @posts.reverse.each_with_index do |post, index| %>
  <%# 6個目以上の記事の場合はBreak %>
  <% if index >= 5
       break
     end
  %>
  <%= link_to post.title, post_path(post) %>
<% end %>

問題点

  • indexのViewが汚れる
  • 仕様変更によって最新記事が他のビュー(ex.posts/show.html.erb)でも必要になったら、また書く必要がある

Controllerが加工処理を受け持った場合

実装方法

app/controllers/posts_controller.rb
def index
  # クエリメソッドで降順並び替え&5件までの呼び出しとしている
  @posts = Post.order(created_at: :desc).limit(5)
end
app/views/posts/index.erb
<% @posts.each do |post| %>
  <%= link_to post.title, post_path(post) %>
<% end %>

問題点

  • 他のアクションやコントローラで最新5件の@postsが必要となった場合、コードが重複する(見通しが悪くなる)
  • 最新記事が5件→10件に仕様変更となったら、すべて書き換えとなってしまう
  • コントローラーで「データ加工」はしちゃいけない

Modelが加工処理を受け持った場合

  • こっちがSkinny Controller, Fat Modelのパターン

実装方法

app/models/post.rb
class Post < ActiveRecord::Base
  scope :latest, -> (limit = 5) { order(created_at: :desc).limit(limit) }
end
app/controllers/posts_controller.rb
def index
  # Modelのscopeを利用する
  @posts = Post.latest
end
app/views/posts/index.erb
<% @posts.each do |post| %>
  <%= link_to post.title, post_path(post) %>
<% end %>

まとめ

  • モデル
    • 共通処理(scope)をもたせる
  • コントローラー
    • モデルの共通処理を操作する
  • ビュー
    • モデルが作ったデータを参照し、ビジュアライズする
wmegane
三鷹でシステム開発を行うメガネ集団(一部伊達)。999.9が好きです。
http://wmegane.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away