I will summarize how to implement the pull-down search function in ActiveHash data. I used a gem called ransack to implement the function.
ransack is a gem that allows for complex searches. This function is a simple search, so you may be able to do it without using ransack. This will be an issue for the future.
--ActiveHash's GitHub page
https://github.com/zilkey/active_hash
-[Rails] Let's make a pseudo model using active_hash
https://pikawaka.com/rails/active_hash
--ransack's GitHub page
https://github.com/activerecord-hackery/ransack
--73 recipes to easily create a search form with Ransack
http://nekorails.hatenablog.com/entry/2017/05/31/173925
This time, I will explain how to display a list of photos in that category after selecting a category using the photo posting app as the subject.
The code is omitted except for the necessary parts (CSS, etc.). The method of creating a pseudo model using ActiveHash is also omitted. We will proceed on the assumption that the pseudo model has been created. Please see the reference page etc. for the creation method.
Gemfile
#Added at the bottom of the file
gem 'ransack'
Terminal
% bundle install
routes.rb
get '/photo/category', to: "photos#category"
Set the category action on the photos controller. Causes the category search results page to be displayed when the category action is executed.
photos_controller.rb
before_action :search_category_photo, only: [:index, :category, :hashtag, :search]
(abridgement)
private
def search_category_photo
@q = Photo.ransack(params[:q])
end
Create a search_category_photo
method in the private method. Doing this will create a search object called @ q = Photo.ransack (params [: q])
.
This time, I stored the search result box in the header. As a result, the search result box is displayed not only on the category search result screen (: category) but also on the top screen (: index), hashtag search result screen (: hashtag), and caption search result screen (: search). I will. Therefore, make sure that before_action
executes the search_category_photo
method when each screen is loaded. Without this I got an error. I had a hard time solving this ...
photos_controller.rb
def category
@photos = @q.result
category_id = params[:q][:category_id_eq]
@category = Category.find_by(id: category_id)
end
Enter @ photos = @ q.result
in the category method to get the search results.
Search parameters are stored in params [: q].
For example, when the category of id: 5 of ActiveHash pseudo model was selected from the pull-down menu, the following items were stored in params [: q].
console
[1] pry(#<PhotosController>)> params[:q]
=> <ActionController::Parameters {"category_id_eq"=>"5"} permitted: false>
In order to display the category name selected in the search result view, I got the category_id ("5" in this example) in params [: q] as category_id = params [: q]: category_id_eq]
. Using that category_id, I got the selected category name as @category = Category.find_by (id: category_id)
.
The following is the ActiveHash pseudo model of the category created this time.
catetory.rb
class Category < ActiveHash::Base
self.data = [
{ id: 0, name: '--' },
{ id: 1, name: 'dog' },
{ id: 2, name: 'Cat' },
{ id: 3, name: 'bird' },
{ id: 4, name: 'fish' },
{ id: 5, name: 'reptiles' },
{ id: 6, name: 'Amphibians' },
{ id: 7, name: 'insect' },
{ id: 8, name: 'Other' }
]
include ActiveHash::Associations
has_many :photos
end
erb:_header.html.erb
<%= search_form_for @q, url: photo_category_path do |f| %>
<%= f.collection_select :category_id_eq, Category.where.not(id: 0), :id, :name, include_blank: "Category search" %>
<%= f.submit 'Search' %>
<% end %>
Create a search form with the helper method search_form_for
method of ransack. The search object @ q
is passed as an argument (see:" 3. Set the action on the controller "). The pathname of the url is the pathname of the category action (checked in rails routes
).
Create a pull-down category selection box with the helper method collection_select
method.
** Note) You may not have a good understanding of the .collection_select method. Below, I would like you to point out any mistakes. ** **
<% = f.collection_select ①: category_id_eq, ②Category.where.not (id: 0), ③: id, ④: name, ⑤include_blank:" Category search "%>
The column name is : category_id
to search by: category_id in the photos table, and the search method is -eq
to get the photos with the same id as the selected category. -eq
is a method that searches according to the conditions (equal image).
Since the data of the Category model of ActiveHash is used, the model name Category
is used as an argument. In .where.not (id: 0)
, id: 0 is not displayed. Instead, in ⑤, include_blank:" category search "
is set, and when not selected, the word "category search" is displayed in the search box. I tried to be done.
Since the value of the id column of the Category model is used for the search, it is set to : id
.
I chose : name
because I want to display the value of: name
instead of : id
of the Category model in the pull-down menu.
Describe the contents of the category search result page in category.html.erb
.
erb:category.html.erb
#Only the parts necessary for implementation are described.
<h2>Category<%= @category.name %></h2>
<ul>
<% @photos.each do |photo| %>
<li>
<%= image_tag photo.image if photo.image.attached? %>
</li>
<% end %>
</ul>
</div>
@category
and @photos
are the instance variables set by the category method of the photos controller above (see "3. Set the action on the controller").
With @ category.name
, I got the category name selected from the pull-down list and displayed it in the search result view.
Since the photos of the category selected from the pull-down list are stored in @ photos
, I took them out one by one with the .each
method and displayed them in the view.
It was difficult to input the arguments of the .collection_select method
, and I came up with the correct answer through many trials and errors. I hope you found this article helpful.
Since this is a beginner, please point out any mistakes or improvements.
Recommended Posts