ransackを使った検索機能
gemransack
を用いると、簡単に検索機能を追加できる
導入
gem 'ransack' $ bundle install
これでransackのインストールは完了
コントローラーの編集
検索するためのアクションを追加します。検索した結果を表示するために新たにsearchアクション
を追加する。
Rails.application.routes.draw do resources :users do collection do get 'search' end end end
このような形でcollection
を使って、/users/search
のURLでsearchアクション
を拾えるようにする。
コントローラに検索を行うための記述をする。
検索結果を取得するコードをprivate以下にメソッド化し、before_actionで呼び出す。そして、searchアクション
を定義する。
class UsersController < ApplicationController before_action :set_q, only: [:index, :search] def search @results = @q.result end private def set_q @q = User.ransack(params[:q]) end
用語 | 説明 |
---|---|
params[:q] | この後に作成するビューファイルから送られてくるパラメーター |
ransackメソッド | 送られてきたパラメーターを元にテーブルからデータを検索するメソッド |
resultメソッド | ransackメソッドで取得したデータをActiveRecord_Relationのオブジェクトに変換するメソッド |
検索フォームの作成
ビューファイルに検索フォームの作成をしていく。
<h1>ユーザー検索</h1> <%= search_form_for @q, url: search_users_path do |f| %> <%= f.label :name_cont, 'ユーザー名' %> <br> <%= f.submit '検索' %> <% end %>
search_form_for
というform_with
のようなメソッドがransackに用意されているのでそれを使う。
_cont
は検索したいカラム名を前に入れると、検索したいカラムに対してあいまい検索がされる。完全一致の場合_eq
がある。
検索結果が表示されるビューを作成
<h1>検索結果</h1> <table> <thead> <tr> <th>Name</th> <th>Age</th> <th>Height</th> <th>Weight</th> <th>Gender</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @results.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.age %></td> <td><%= user.height %></td> <td><%= user.weight %></td> <td><%= user.gender %></td> <td><%= link_to 'Show', user %></td> <td><%= link_to 'Edit', edit_user_path(user) %></td> <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <%= link_to 'Top', users_path %>
<% @results.each do |user| %>
の部分で結果をもとに繰り返し表示させている。
参考
jsの$()とか#とか
課題17
$("#error_messages").remove()
まず、このコードを細かく見ていく。"#error_messages"
は、idがerror_messagesのものを対象とする、という意味で、removeは外すという意味なので、idがerror_messagesの表示があれば削除してくださいね、ということになる。これがないとどんどんエラーメッセージが溜まってしまう。
<% if @comment.errors.present? %> $("#new_comment").prepend("<%= j(render('shared/error_messages', object: @comment)) %>") <% else %> $("#js-table-comment").prepend("<%= j(render('comments/comment', comment: @comment)) %>") $("#js-new-comment-body").val('') <% end %>
少し長いけど、きちんと理解できるようにする。 一行目は、@commentにエラーがあるかどうかで分岐させている。エラーがあればtrue,なければfalseで分岐。
trueなら、idがnew_commentを対象にして、prepend(対象の前に挿入する)をしている。prependの中身は(" ")で囲んでいるので文字列にしている。erbなので、<%= %>で呼び出している。
j()
はActionView::Helpers::JavaScriptHelper#escape_javascript
のエイリアス。改行コード、シングルクォート、ダブルクォートをJacaScript用にエスケープしてくれる。エスケープとは、プログラム内で使用できない文字を、大体の文字に置き換えること。
render('shared/error_messages',object: @comment)では、sharedディレクトリの_error_messages.html.erbを呼び出す。その際にobjectを@commentに置き換えて呼び出す。
falseの場合、elseが処理されるので、$("js-table-comment")
を対象として、その先頭に("<%= j(render('comments/comment', comment: @comment)) %>")を呼び出す。ということになる。
$("#js-new-comment-body").val('')
は、idがjs-new-comment-bodyの値を''
にするという動きをする。
参考
paginateとkaminari
paginateってなんだ?
ページ下部にある123とかってやつ。これを実装するために、kaminari
というgemをインストールする。
実装
gem 'kaminari' $ bundle instal
これでkaminari
を使えるようになった。どう実装するのか。
rails g kaminari:config
でkaminariのコンフィグを作る。そうすると、config/initializers/kaminari
に
# frozen_string_literal: true Kaminari.configure do |config| # config.default_per_page = 25 # config.max_per_page = nil # config.window = 4 # config.outer_window = 0 # config.left = 0 # config.right = 0 # config.page_method_name = :page # config.param_name = :page # config.max_pages = nil # config.params_on_first_page = false end
とできるので、自由にいじる。
controllerに追加
ページネーションを追加したいアクションにpage(params[:page])
を追加する。app/controller/boards
def index @boards = Board.all.page(params[:page]) end
として、表示したいview、今回はapp/views/boards/index.html.erb
に
<%= paginate @boards %>
と書き込むと、ページネーションが表示されるようになる。
ページネーションの見た目
見た目を変えるために
$ rails g kaminari:views bootstrap4
ってすると見た目が変わり、よきよきになる。
参考
https://www.autovice.jp/articles/139 https://qiita.com/rio_threehouse/items/313824b90a31268b0074
testを作る際のsetupメソッドとは
setupメソッドとは
testを作る際に、
def setup @user = User.new(name:"hoge",nickname:"fuga") end
などとしてsetupメソッドを定義することがある。このsetupメソッドは、他のテストが実行される前にかならず実行されるものになっていて、他のテストの中で、@user
を使うこともできるようになっている。
参考
findとfind_byの違い
Userのidが1のデータがあると仮定する。
User.find(1) User.find_by(id: 1)
では同じようにUserのidが1のデータを取ってくるが、存在しないUserのidが2のデータを取ってこようとすると、
User.find(2) # => errorが出る。 User.find_by(id: 2) # => nilを返す。
という違いがある。
test assert_selectメソッドについて
testで使うassert_selectメソッドは特定のHTMLタグが存在するかどうかをテストしてくれます。「セレクタ」と呼ばれることもあります。
assert_select "title","Home | Sample App"
と書くと、title
タグ内にHome | Sample App
という文字列があるかどうかをチェックします。