7つの基本アクション以外でルーティングを定義する時には、collectionかmemberを利用します。
collectionはルーティングに:idがつかない、memberは:idがつく。という違いがあります。
今回は検索機能なので:idが不要なcollectionを使用します。
config/routes.rb
Rails.application.routes.draw do
resources :tweets do
collection do
get 'search'
end
end
end
モデルファイルに対してwhereメソッドとLIKE句を使用して検索の処理を作ります。
LIKE句は、曖昧な文字列の検索をすることができ、whereメソッドと一緒に使います。
app/models/tweet.rb
class Tweet < ApplicationRecord
validates :text, presence: true
belongs_to :user
has_many :comments
def self.search(search)
return Tweet.all unless search
Tweet.where('text LIKE(?)', "%#{search}%")
end
end
コントローラファイルに対して以下の記述を追加します。
app/controllers/tweets_controller.rb
class TweetsController < ApplicationController
def search
@tweets = Tweet.search(params[:keyword])
end
end
検索フォームを追加するページに検索フォームを実装します。
検索フォーム
<%= form_with(url: search_tweets_path, local: true, method: :get) do |form| %>
<%= form.text_field :keyword, placeholder: "投稿を検索する", class: "sample"%>
<%= form.submit "検索", class: "sample"%>
<% end %>
app/views/tweetsに検索結果用のビューファイルsearch.html.erbを追加し、検索結果を表示させる。
app/views/tweets/search.html.erb
<% @tweets.each do |tweet| %>
<%= tweet.content %>
<% end %>
##複数のカラムから検索したい場合
modelファイルを下記のように編集します。
app/models//tweets
def self.search(search)
return Tweet.all unless search
Tweet.where("title LIKE(?) or content LIKE(?)", "%#{search}%", "%#{search}%")
end