0
0

投稿機能の検索機能の実装

Posted at

検索機能は必須機能ではないですがあると便利ですね!
テックキャンプの備忘録です!

目的

  • ルーティングのcollectionとmemberを理解
  • 検索に必要なメソッドを理解

seachアクションのルーティング設定

collectionとmember

ルーティングを設定する際に使用でき、生成されるルーティングのURLと実行されるコントローラを任意でカスタムできる
ルーティングに:idがつくかつかないかの違い
config/routes.rb

Rails.application.routes.draw do
  devise_for :users
  root to: 'tweets#index'
  resources :tweets do
    resources :comments, only: :create
    collection do
      get 'search'
    end
  end
  resources :users, only: :show
end

検索フォーム作成

app/views/tweets/index.html.erb

<%= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form| %>
  <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
  <%= form.submit "検索", class: "search-btn" %>
<% end %>

検索のメソッドをモデルで定義

ビジネスロジック

データに対する処理などを行うプログラム処理
「データをどのように処理するのか」
「どのデータを取得するのか」
「どのような手順で処理をしていくのか」 など指す。

whereメソッド

ActiveRecordメソッドの一つ
モデル.where(条件)のように、引数部分に条件を指定することで、テーブル内の「条件に一致したレコードのインスタンス」を配列で取得できる
モデル.where('検索対象となるカラムを含む条件式')

LIKE句

曖昧な文字列の検索をするときに使用 whereと一緒に

class Tweet < ApplicationRecord
  validates :text, presence: true
  belongs_to :user
  has_many :comments

  def self.search(search)
    if search != ""
      Tweet.where('text LIKE(?)', "%#{search}%")
    else
      Tweet.all
    end
  end
end

引数のsearchは、検索フォームから送信されたパラメータが入るため、
if search != ""と記述し、検索ふぉーむに何かが入力されていた場合を条件としています。
もし検索ふぉーむに何も入力をせずに検索ボタンを押すと、引数で渡されるsearchの中身は空になります
この場合elseに該当し、Tweet.allという記述は、その時全ての投稿を取得して表示するためのもの
テーブルとのやりとりに関するメソッドはモデルに置く という意識が必要

searchアクションをコントローラーに定義

~~
before_action :move_to_index, except: [:index, :show, :search]
~~
  def search
   @tweets = Tweet.search(params[:keyword])
 end
~~

Tweetモデルに書いたsearchメソッドを呼び出し、
seachメソッドの引数にparams[:keyword]と記述して、検索結果を渡す
未ログイン時に検索するとトップページにリダイレクトされるのでbefore_actionのexceptオプションに:search追加

検索結果のビュー作成

app/views/tweets/search.html.erbを作成

<%= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form| %>
 <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
 <%= form.submit "検索", class: "search-btn" %>
<% end %>
<div class="contents row">
 <% @tweets.each do |tweet| %>
   <%= render partial: "tweet", locals: { tweet: tweet } %>
 <% end %>
</div>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0