Railsアプリの設計をMVCごとに見直しリファクタリングして連載総まとめ:開発現場でちゃんと使えるRails 4入門(12)(1/2 ページ)
エンタープライズ領域での採用も増えてきたRuby on Railsを使ってWebアプリケーションを作るための入門連載。最新版の4に対応しています。今回は、サンプルプロジェクトをMVCごとにRailsアプリの設計を見直してリファクタリングすることで、これまでの連載のおさらいをします。
前回の『「設定より規約」のRailsで必要なセッティングの基礎知識と国際化/多言語対応』まで、サンプルプロジェクトの「book_library」を題材にRailsのさまざまな機能を紹介してきましたが、今回はRailsアプリケーション開発を紹介してきた本連載のおさらいとして、サンプルプロジェクトをMVCごとにリファクタリングしたいと思います。
「book_library」は社内の書籍を管理するためのアプリケーションで、これまでRailsの各機能を紹介するため場当たり的にさまざまな機能を盛り込んできましたが、もっとシンプルに作ってみましょう。
コントローラーの見直し
まずは、連載第7回の「Rails開発を面白くするアクションコントローラーの5大機能とルーティングの基本」で解説したMVCの「C」、コントローラーです。コントローラーの見直しは名前空間やネストによる外部構造と、アクションの定義などの内部構造に分けて進めていきます。
外部構造の見直し
コントローラーの外部構造は「ルーティング」により定義されますが、それに従って「app/controllers」以下のファイルの配置も決まります。現在の「config/routes.rb」は次のコードのようになっていますが、注意して変更していきます。
BookLibrary::Application.routes.draw do
root 'books#index'
resources :books
resources :users do
get 'booking', on: :collection
post 'message', on: :member
resources :books, only: %i(index)
end
namespace :admin do
resources :books, only: %i(index)
end
get 'admin' => 'admin/books#index'
get 'admin/:id' => 'admin/books#show'
post 'admin' => 'admin/books#create'
end
まず2行目の「root」の定義ですが、これはこのままでもよいでしょう。
ですが、次の「resources :books」と「namespace :admin」のブロック内の「resources :books」はいずれも「books」のリソースを取り扱うルーティングです。しかし、本来であれば管理側でリソースの登録や更新、削除などをしたいところです。
一方、4行目の「resouces :users」はユーザー自身にユーザー登録や更新する操作をさせたいので、このままとしておきます。しかし、このブロック内部の「get」や「post」は必要な処理かもしれませんが、「resources :books」は「index」アクションだけでそれほど重要ではないかもしれません。
最後の「get」や「post」によるルーティングは連載中の説明のために追加しましたが、見るからに違和感がありますね。「namespace :admin」のルーティングで同じアクションを扱えるので削除してしまってもいいでしょう。
以上の内容を踏まえてルーティングを再定義すると、次のようになりました。ちなみに「namespace :admin」のブロック中で「root」を定義すると、「/admin」のルーティングを設定できます。
BookLibrary::Application.routes.draw do
# ユーザーサイド
root 'books#index'
resources :books, only: %w(index show)
resources :users do
get 'booking', on: :collection
post 'message', on: :member
end
# 管理者サイド
namespace :admin do
root 'books#index'
resources :books
end
end
内部構造の見直し
前節のルーティングの再定義により、コントローラーごとにアクションを見直す必要があります。まず「BooksController(app/controllers/books_controller.rb)」から取り掛かりましょう。
このコントローラーは連載初期に「scaffold」により生成し、そのまま使ってきました。ですが、「new」「create」「edit」「update」「destroy」のアクションは「Admin::BooksController(app/controllers/admin/books_controller.rb)」に移動させたいと思います。対象の部分を切り取って、フィルターのオプションなどを整理すると「BooksController」は次のようになります。
class BooksController < ApplicationController
before_action :set_book, only: [:show]
def index
@query = Query.new(params[:query])
if @query.valid?
@books = Book.where("title like :keyword OR author like :keyword", keyword: @query.keyword)
else
@books = Book.all
end
end
def show
end
private
def set_book
@book = Book.find(params[:id])
end
end
切り取った部分は「Admin::BooksController」で再利用しますが、リダイレクト先やビューのリンクなどが「admin」名前空間の中でないため、適宜修正する必要があります。修正した内容については「book_library」の「11」ディレクトリのコードを参照してください。
また、ビューに関しては削除したアクションへのリンクなど不必要なものを取り除きます。「index」アクションのビューを次に示します。
h1 = t('.title')
= form_for @query, url: books_path, method: :get do |f|
= f.text_field :keyword
= f.submit '検索'
table
thead
tr
th Title
th Author
th Outline
tbody
- @books.each do |book|
tr
td = link_to book.title, book
td = book.author
td = book.outline
スペック(spec)の追加
ここまででも「books#index」のリファクタリングができましたが、次の変更に備えてスペック(spec)を追加しておくのも良い考えです。「spec/controllers/books_controller_spec.rb」に次のように「index」アクションなどのテストを追加します(テストについては連載代9回の「RailsテストフレームワークRSpecのインストールと基本的な使い方、基礎文法」を参照してください)。
require 'rails_helper'
RSpec.describe BooksController, :type => :controller do
describe "index" do
# @queryにQueryのインスタンスが代入される
it "assigns a query as @query" do
get :index, {}, {}
expect(assigns(:query)).to an_instance_of Query
end
# クエリがないとき、@booksに全てのBookが代入される
it "assigns all books as @books without query" do
b1 = Book.create!(title: 'hoge')
b2 = Book.create!(title: 'fuga')
get :index, {}, {}
expect(assigns(:books)).to eq [b1, b2]
end
# @booksにクエリで要求されたBookが代入される
it "assigns books as @books required by query" do
b1 = Book.create!(title: 'hoge')
b2 = Book.create!(title: 'fuga')
get :index, {query: {keyword: 'hoge'}}, {}
expect(assigns(:books)).to eq [b1]
end
end
……
end
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
Ruby on Rails 4.1でDevOps環境を考慮した体系的な知識を付ける
エンタープライズ領域での高速なWebアプリケーション開発にも採用され始めているRuby on Rails。最新版である4.1の実践的な解説書が登場した。DevOps環境を前提としたチュートリアルが掲載されているなど、現代的な内容になっている。- @IT自分戦略研究所 資格辞典:Rails技術者認定試験(Rails 3 Certified Programmer)
- 資格試験は転職に役立つか:Rails技術認定試験がスタート、合格者に聞いた