I implemented the partial match search function without using Ransuck, so I will summarize it. This time, we will create a simple function that allows you to enter the name and email address and get the information of the corresponding user by partial match.
Example
Search for "no" in the name form and "" in the email address form
↓
Nobita Nobi [email protected]
It feels like output. I want to
From the conclusion, I will post the code first.
routes.rb
Rails.application.routes.draw do
root 'users#index'
resources :users
end
index.html
<h1>Let's do a partial match search for Doraemon characters</h1>
<%= form_with(url: 'users', local: true, method: :get) do |f| %>
<span class="small">Search target: Name Email address</span>
<div>
<%= f.label :name, 'name' %>
<%= f.text_field :name , value: @search_params[:name] %>
</div>
<div>
<%= f.label :email, 'mail address' %>
<%= f.text_field :email, value: @search_params[:email] %>
</div>
<%= f.submit 'Search', class: 'btn btn-default' %>
<%end%>
<h1>search results</h1>
<% @users.each do |user| %>
<%= user.name %>
<%= user.email %>
<% end %>
users_controller.rb
class UsersController < ApplicationController
def index
@search_params = search_params
@users = User.search(search_params)
end
private
def search_params
params.permit( :name, :email )
end
end
user.rb
class User < ApplicationRecord
scope :search, -> (search_params) do
return if search_params.blank?
name_like(search_params[:name] )
.email_like(search_params[:email])
end
scope :name_like, -> (name){where("name LIKE ?" ,"%#{name}%")}
scope :email_like, -> (email){where("email LIKE ?", "%#{email}%")}
end
schema.rb
ActiveRecord::Schema.define(version: 2020_10_10_011424) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
seeds.rb
User.create!(name: "Nobita Nobi",email: "[email protected]")
User.create!(name: "Takeshi Goda",email: "[email protected]")
User.create!(name: "Suneo Honekawa",email: "[email protected]")
User.create!(name: "Doraemon",email: "[email protected]")
User.create!(name: "Dorami-chan",email: "[email protected]")
User.create!(name: "Source Shizuka",email: "[email protected]")
I will explain each one. First from the explanation of view
index.html
<h1>Let's do a partial match search for Doraemon characters</h1>
<%= form_with(url: 'users', local: true, method: :get) do |f| %>
<span class="small">Search target: Name Email address</span>
<div>
<%= f.label :name, 'name' %>
<%= f.text_field :name , value: @search_params[:name] %>
</div>
<div>
<%= f.label :email, 'mail address' %>
<%= f.text_field :email, value: @search_params[:email] %>
</div>
<%= f.submit 'Search', class: 'btn btn-default' %>
<%end%>
<h1>search results</h1>
<% @users.each do |user| %>
<%= user.name %>
<%= user.email %>
<% end %>
First of all, here
<%= form_with(scope: :search ,url: 'users', local: true, method: :get) do |f| %>
The search form uses form_with. The difference between form_tag and form_for is explained in an easy-to-understand manner at the following URL. https://qiita.com/hmmrjn/items/24f3b8eade206ace17e (Previously, form_tag was used when there was no related model, but form_for was used when there was a related model, but it is deprecated in rails 5.1. As a concrete example, I just want to use User information ( When searching) etc. is form_tag I want to register User information → I used form_for when the database to be registered existed. ) Form_with, which has been recommended since rails 5.1, divides the processing around it nicely and executes it. Also, Ajax for asynchronous communication is implemented by default. Since JS is not used this time, local: true is specified to invalidate the remote form, and the data is communicated by method: get in HTML format.
Next, let's look at the controller.
class UsersController < ApplicationController
def index
@search_params = search_params
@users = User.search(search_params)
end
private
def search_params
params.permit( :name, :email )
end
end
The miso here is User.search (search_params). This is the search method, but the user model is scoped to the partial match search function. For the sent value, search returns a partial match to name and email. Then refer to model.
user.rb
class User < ApplicationRecord
scope :search, -> (search_params) do
return if search_params.blank?
name_like(search_params[:name] )
.email_like(search_params[:email])
end
scope :name_like, -> (name){where("name LIKE ?" ,"%#{name}%")}
scope :email_like, -> (email){where("email LIKE ?", "%#{email}%")}
end
The search scope will fly to here, perform partial processing one by one, and then be returned to the controller. return if search_params.blank? By putting, even if no value is entered, the process will be stopped there and returned to the controller. If the search target is multiple such as: name: email like this time, params is iteratively processed and the search is returned one by one.
That's all for this time. If there was something different here, please point out more and more.
Recommended Posts