はじめに
今日の内容は投稿検索機能の実装。簡単な内容なので初学者でもできるはず!
早速始めていきます!
投稿検索機能実装
まずはビューから!
<%= form_with(url: search_posts_path, local: true, method: :get, class: "search-form") do |form| %>
<%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
<%= form.submit "検索", class: "search-btn" %>
<% end %>
form_withのtext_field
とsubmit
を使って検索窓と検索ボタンを作成しました。
続いてsearchアクションのルーティングを設定していきます。
の前にcollection
とmember
を設定していきます。
collectionとmemberは、ルーティングを設定する際に使用します。
使用すると、生成されるルーティングのURLと実行されるコントローラーを任意にカスタムできます。
例:collection
Rails.application.routes.draw do
resources :posts do
collection do
get 'search'
end
end
end
ルーティング↓
Prefix Verb URI Pattern
search_posts GET /posts/search(.:format) posts#search
例:member
Rails.application.routes.draw do
resources :posts do
member do
get 'search'
end
end
end
ルーティング↓
Prefix Verb URI Pattern
search_posts GET /app/:id/search(.:format) posts#search
この違い分かりますか?
URLの指定先がcollectionは:idなし
、memberは:idあり
となっていることが確認できます。
つまり違いはidがあるかないか!
今回は以下のように指定します。
Rails.application.routes.draw do
devise_for :users
root to: 'posts#index'
resources :posts do
resources :comments, only: :create
collection do
get 'search'
end
end
resources :users, only: :show
end
続いてposts.rbを編集
class Post < ApplicationRecord
validates :text, presence: true
belongs_to :user
has_many :comments
def self.search(search)
if search != ""
Post.where('text LIKE(?)', "%#{search}%")
else
Post.all
end
end
end
記述について少し補足します。
whereメソッド
モデルが使用できるActiveRecordメソッドの1つ。モデル.where(条件)
の記述でテーブル内の条件に一致したレコードのインスタンスを配列の形で取得できます。
※whereを連続して記述することで、複数の条件に一致したレコードを取得することもできます。
LIKE句
曖昧な文字列の検索をする際に使用します。上記のようにwhereメソッドと一緒に使用しましょう。
参考
曖昧文字列
文字列 | 意味 |
---|---|
% | 任意の文字列 |
_ | 任意の1文字 |
実行例
実行例 | 意味 |
---|---|
where('title LIKE(?)', "a%") | aから始まるタイトル |
where('title LIKE(?)', "%b") | bで終わるタイトル |
where('title LIKE(?)', "%b") | cが含まれるタイトル |
where('title LIKE(?)', "d_") | dで始まる2文字のタイトル |
where('title LIKE(?)', "_e") | eで終わる2文字のタイトル |
上記を参考にposts.rbを編集します。
class Post < ApplicationRecord
validates :text, presence: true
belongs_to :user
has_many :comments
def self.search(search)
if search != ""
Post.where('text LIKE(?)', "%#{search}%")
else
Post.all
end
end
end
続いてposts/controller.rbをに追記していきます。
#略
before_action :move_to_index, except: [:index, :show, :search]
#略
def search
@tweets = Tweet.search(params[:keyword])
end
#略
最後に検索結果をビューに表示しましょう。
<%= form_with(url: search_posts_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">
<% @posts.each do |post| %>
<%= render partial: "post", locals: { post: post } %>
<% end %>
</div>
以上です!
上手く記述できていれば、検索した結果がビューに表示されるはず!
終わりに
完全に余談です。
毎日Qiitaを投稿し、基本的な実装や知識をアウトプットしています。
今日は時間ギリギリでした。
またまた、エラーと戦ってきます!エラーのせいで全然進まん!