今回の作業を行っていく上で config/locales/views/*.yml の変更時に Guard が反応しませんでした。Guardfile に以下の行を追加します。
watch(%r{^config/locales/views/(.+)\.yml$}) { "spec" }
また、haml を修正時には feature を実行したいので、同様に Guardfile を修正します。
watch(%r{^app/views/(.*)/.*\.html\.haml$}) { |m| "spec/acceptance/#{m[1]}_page.feature" }
仕様策定
モデルができたので、コントローラを作成していきます。先に仕様を考えます。
一覧表示の作成
まず、一覧表示のページ遷移の feature を書きます。
# encoding: utf-8 # language: ja 機能: タイトルに関する CRUD を確認する シナリオ: タイトルページにアクセスする 前提 トップページを表示する もし "[タイトル]" をクリックする ならば 画面に "タイトル一覧" と表示されていること
当然ながら[タイトル]というリンクがないのでエラーになります。
Failure/Error: もし "[タイトル]" をクリックする Capybara::ElementNotFound: Unable to find link "[タイトル]"
app/views/shared/_top_link_bar.html.haml に titles_path へのリンクを追加します。
%table %tr %td=link_to lh(t 'link.home'), root_path %td=link_to lh(t 'link.titles'), titles_path
また、config/locales/views/ja.yml, config/locales/views/en.yml も更新しておきます。
link: home: 'ホーム' titles: 'タイトル'
link: home: 'Home' titles: 'Titles'
まだ routing 設定をしていないので、以下のようにエラーとなります。
Failure/Error: もし "[タイトル]" をクリックする ActionView::Template::Error: undefined local variable or method `titles_path' for #<#<Class:0x007fb41ecc8308>:0x007fb41e92b718>
config/routes.rb に titles に関する routing 情報を追加します。今回は、CRUD を全部設定する予定なので、フィルタリングは行いません。
MoritakaDb::Application.routes.draw do root 'top#index' resources :titles end
Guard の結果は以下のようになります。
Failure/Error: もし "[タイトル]" をクリックする ActionController::RoutingError: uninitialized constant TitlesController
TitlesController がないと言われるので、generator で作成します。
r g controller titles
Guard の結果は以下のようになります。
Failure/Error: もし "[タイトル]" をクリックする AbstractController::ActionNotFound: The action 'index' could not be found for TitlesController
index がないので、app/controllers/titles_controller.rb にメソッドを作成します。取り急ぎ中身は空にしておきます。
def index end
こんどは view がないというエラーになります。
Failure/Error: もし "[タイトル]" をクリックする ActionView::MissingTemplate: Missing template titles/index, application/index with {:locale=>[:ja], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee, :haml]}. Searched in: * "/Users/hkob/rails/moritaka-db/app/views" * "/Users/hkob/rails/moritaka-db/vendor/bundle/ruby/2.1.0/gems/kaminari-0.15.1/app/views"
とりあえず、app/views/titles/index.html.haml にタイトルだけ表示します。top/index と同じ表記です。
%h1=t '.title'
ローカライズされていないので、Title とだけ表示されており、エラーになっています。
Failure/Error: もし "[タイトル]" をクリックする expected to find text "タイトル一覧" in "[ホーム] [タイトル] [English] Title"
ローカライズを追加することでテストを通過させます。
titles: index: title: "タイトル一覧"
titles: index: title: "List of titles"
これでテストが通過しました。
開発環境と運用環境
今回、開発環境では編集を可能とし、運用環境では閲覧のみを行うことにしました。そこで、production 環境以外(development, test) においては、@is_dev という変数を true とすることにします。locate の設定のために、app/controllers/application_controller.rb にて set_locale というメソッドを before_action しているので、その時に一緒に設定することにします。
def set_locale I18n.locale = params[:locale] || I18n.default_locale @is_ja = I18n.locale == :ja @is_dev = ! Rails.env.production? end
まず、運用環境でタイトルが追加できなくなっているかをテストします。
シナリオ: 運用環境ではタイトル追加ができない 前提 運用環境である かつ タイトル一覧を表示する ならば 画面に "[タイトル追加]" と表示されていないこと
これらの step を書いていきます。最初の最後の step はどこでも使用することがあるため、top_page_steps.rb に記載することにします。本来なら共通部品用の steps を書くべきなのかもしれません。
step '画面に :string と表示されていないこと' do |string| expect(page).not_to have_content(string) end step "運用環境である" do Rails.stub_chain(:env, :production).and_return(true) Rails.stub_chain(:env, :development).and_return(false) end
その後、spec/acceptance/steps/titles_page_steps.rb を記載します。
# encoding: utf-8 step 'タイトル一覧を表示する' do visit titles_path end
そもそも、タイトル追加と書いていないのでテストは通過しています。引き続き app/views/titles/index.html.haml にタイトル追加リンクを記述してみます。まずは普通に書いてエラーになることを確認します。また、両方の locales に titles: new: title: を追加しておきます。
%h2=t 'titles.new.title' %table %tr %td=link_to lh(t 'titles.new.title'), new_title_path
Guard でエラーになりました。タイトル追加のリンクが表示されているのであたりまえですね。運用環境でこのリンクが表示されないように、@is_dev の時のみ表示するようにします。
-if @is_dev %h2=t 'titles.new.title' %table %tr %td=link_to lh(t 'titles.new.title'), new_title_path
これで開発環境と運用環境で処理が別れていることがわかります。長くなってしまったのでこの続きは後日。
written by iHatenaSync