When creating the portfolio, I implemented a search function, so I will post an article as a memo.
app/views/tweet/index
= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form|
= form.text_field :keyword, placeholder: "Search for posts", class: "search-input"
= form.submit "Search", class: "search-btn"
routes
resources :tweets do
resources :comments, only: :create
collection do #add to
get 'search' #add to
end #add to
~abridgement~
end
It will be displayed as below.
** In rails, there are collection and member as a way to configure routing other than 7 actions **
- | - |
---|---|
collection | For routing:id is not attached |
member | For routing:id is attached |
** This time, I will use. ** ** ** Once defined, do rails routes and see for yourself. ** **
Define a method search for searching from the table in the model.
Logic such as searching from the viewpoint of MVC should be defined collectively in the model as a method.
** Define the search method in the Tweet model. Use the where method and the LIKE clause to get posts that contain the keywords you searched for. ** **
Add the following to app / models / tweet.rb.
def self.search(search)
if search
Tweet.where('text LIKE(?)', "%#{search}%")
else
Tweet.all
end
end
One of the ActiveRecord methods. By specifying the condition in the argument part like model .where (condition), you can get the instance of the record that matches the condition in the table in the form of an array.
Be sure to include the "column to be searched" in the argument condition and describe the conditional expression.
model.where('Conditional expression including the column to be searched')
The LIKE clause allows you to search for ambiguous strings and is used with the where method.
For example, when you want to search for data that contains the character string'a'in the first character, data that contains'b' in the last character, or data that contains'c' in the middle of the character string, an ambiguous character. Searching using columns.
Execution example | Execution example |
---|---|
where('title LIKE(?)', "a%") | Titles starting with a |
where('title LIKE(?)', "%b") | Titles ending in b |
where('title LIKE(?)', "%c%") | Titles containing c |
where('title LIKE(?)', "d_") | Two-letter title starting with d |
where('title LIKE(?)', "_e") | Two-letter title ending in e |
Call the search method written in the model. The search result is passed by writing params [: keyword] in the argument of the seach method.
Also, in order to avoid being redirected to the top page when not logged in,: search is added to the except option of before_action.
app/controllers/tweets_controller.rb
before_action :move_to_index, except: [:index, :show, :search]
def search
@tweets = Tweet.search(params[:keyword])
end
~abridgement~
private
def move_to_index
redirect_to action: :index unless user_signed_in?
end
The description is below
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: "Search for posts", class: "search-input"
= form.submit "Search", class: "search-btn"
.contents.row
- @tweets.each do |tweet|
= render partial: "tweet", locals: { title: tweet }
The description of the tweet part template is as follows in my case. It's still incomplete, but it worked fine here for the time being. app/views/tweets/_tweet.html.erb
.users_tweets
- @tweets.each do |tweet|
.users_tweets__lists
.users_tweets__lists_list
.users_tweets__lists_list__tweet_image
= link_to tweet_path(tweet) do
= attachment_image_tag tweet, :image
= tweet.title
.users_tweets__lists_list__user_image
= link_to user_path(tweet.user.id) do
= attachment_image_tag tweet.user, :profile_image, fallback: "no-image.png "
= link_to tweet.user.username,user_path(tweet.user.id)
.users_tweets__lists_list__user_name
= tweet.updated_at.strftime("%Y-%m-%d %H:%M")
Update date
- if current_user.already_liked?(tweet)
= link_to tweet_likes_path(tweet), method: :delete do
%i.fas.fa-heart
- else
= link_to tweet_likes_path(tweet), method: :post do
%i.far.fa-heart
= tweet.likes.count
I think you can implement it with this!
If you get an error, please comment.
Thank you very much!
Recommended Posts