Ruby on Rails5速習実践ガイド を読んだので、個人的に気になったことなどをまとめてます。
学んだこと
RSpec, Capybara, FactoryBotを用いたテストコード
- Rspec:Rubyのテスティングフレームワーク
- Capybara:WebアプリケーションのE2Eテスト用フレームワーク(Rails 5.1からデフォルトで同梱されている)
- FactoryBot:テスト用データ作成のgem
-
RSpecインストール
Gemfilegem 'rspec-rails', '-> 3.7' gem 'factory_bot_rails', '-> 4.11'
bash$ bundle $ rails g rspec:install
-
Capybaraの設定
spec/spec_helper.rb
にブラウザにHeadless Chromeを使うことを記述。spec/spec_helper.rbrequire 'capybara/rspec' # 追記 RSpec.configure do |config| # 追記 config.before(:each, type: :system) do driven_by :selenium_chrome_headless end ...
-
FactoryBotでテストデータを作成
spec/factories/users.rbFactoryBot.define do factory :user do name { 'テストユーザ' } email { 'test1@example.com' } passsword { 'password' } end end
-
テストコードを作成
rspecテンプレートdescribe '~機能(テスト対象)', type: :system do describe '登録' do context '○○の場合(ある状況・状態)' do before do # 事前処理 end it '○○する(期待される値・概要)' do # 期待する処理 end end context '××の場合(ある状況・状態)' do before do # 事前処理 end it '××する(期待される値・概要)' do # 期待する処理 end end end describe '削除' do # 略 end end
-
テスト実行
$ bundle exec rspec spec/system/tasks_spec.rb
ransackを用いた検索機能
-
ransackインストール
Gemfilegem 'ransack'
$ bundle
-
ソート処理を追記
app/controller/tasks_controller.rbdef index @q = current_user.tasks.ransack(params[:q]) @tasks = @q.result(distinct: true).recent end
-
ソート項目入力欄・を追記
app/views/index.html.slim= seach_from for @q, class: 'mb-5' do |f| .form-group.row =f.label :name_cont, '名称', class: 'col-sm-2 col-form-label' .col-sm-10 = f.search_field :name_cont, class: 'form-control' .form-group.row =f.label :created_at_gteq, '登録日時', class: 'col-sm-2 col-form-label' .col-sm-10 = f.search_field :created_at_gteq, class: 'form-control' .form-group f.submit class: 'btn btn-outline-primary' ...
-
項目名の横のソートボタンでソートを実行
app/views/index.html.slimtr th = sort_linke(@q, :name) th = Task.human_attribute_name(:created_at) th ...
app/models/task.rb# 検索対象にすることを許可するカラムを指定する class Task < ApplicationTecord def self.randsackble_attributes(auth_object = nil) %w[name created_at] end def self.ransackble_associations(auth_object = nil) [] end end
kaminariを用いたページネーションの実装
-
kaminariインストール
Gemfilegem 'kaminari'
$ bundle
-
controllerにページネーション機能を追加
pp/controllers/tasks_controller.rbdef index ... @tasks = @q.result(distinct: true).page(params[:page]) ...
-
ビューにページネーションを追加
app/views/tasks/index.html.slim.mb-3 = paginae @tasks = page_entries_info @tasks
-
日本語化
config/locales/kaminari.ja.ymlja: views: pagination: first: "« 最初" last: "最後 »" previous: "&lasquo; 前" next: "次 ›" truncate: "…" helpers: page_entries_info: one_page: display_entries: zero: "%{entry_name}がありません" one: "1件の%{entry_name}が表示されています" other: "%{count}件の%{entry_name}が表示されています" more_pages: display_entries: "全%{total}件中 %{first} - %{last}件の%{entry_name}が表示されています"
-
パーシャルテンプレート生成
$ rails g kaminari:views bootstrap4
-
表示件数の変更方法
表示件数の変更方法は以下3パターンある-
コントローラに記述
app/controllers/tasks_controller.rb@tasks = @q.result(distinct: true).page(params[:page]).per(50)
-
モデルに記述
app/models/task.rbclass Task < ApplicationRecord paginates_per 50
-
コンフィグファイルに記述
$ rails g kaminari:config
config/initializers/kaminari_config.rbKaminari.configure do |config| config.defalut_per_page = 50 ...
-
良かったところ
一覧画面での検索・ソート機能、メール送信、ファイルのアップロードなど、
一般的に使用される機能の実装方法を網羅的に学ぶことができた。
また、保守や実運用後の話があり、保守性を意識した開発を心掛けるきっかけとなった。
難しかったこと
自分がJavascriptの知識がないということもあるが、Javascript の連携の箇所が難しかった。
内容は理解はできるが、こういう処理をするコードを書いてねと言われたときに、
書ける自信がないので、Javascriptとの連携処理を書くときがきたら、再度読み直したいと思う。
参考文献