Problem Description: I want to display an icon (from Semantic UI) next to a column name that has been clicked upon. A user would click this column to sort the list by that column.
Basically, I am working with a list of movies with columns - Title, Rating, Description, and Release Date. I have made 'Title' and 'Release Date' into clickable links which, upon clicking, sort the movie list by Title/Release Date.
My routes.rb file:
Rails.application.routes.draw do
root 'movies#index'
resources :movies
end
In my index.html.erb file, I have made Title and Release Date as such:
<%= link_to "Title", movies_path(sort: "title") %>
<%= link_to "Release Date", movies_path(sort: "release_date") %>
In my movies_controller.rb, I am fetching all movie entries and sorting them with the help of order
- Movie.all.order(params[:sort])
.
All of this is working fine.
What I want to be able to do next is display an icon (<i ></i>
) next to the column name which has been clicked upon.
My idea was to leave <i ></i>
empty, and then set a variable inside movies_controller#index to chevron up icon
, and then conditionally set it based upon params[:sort]
, and then render it in the view. But I don't think this would be the right way to do it, because it wouldn't work for both Title and Release Date.
I am seeking the correct way to do this. Would I have use one of the helper files - application_helper.rb or movies_helper.rb? Somebody please explain the logic to me. I am, as you should be able to tell by now, a beginner in Rails, so pardon me for my ignorance.
Edit: Sreenshot to get a better understanding of what I am working with
CodePudding user response:
In ERB you could solve this with:
<%= link_to movies_path(sort: "title") do %>
Title
<% if params[:sort] == "title" %>
<i ></i>
<% end %>
<% end %>
<%= link_to movies_path(sort: "release_date") do %>
Release Date
<% if params[:sort] == "release_date" %>
<i ></i>
<% end %>
<% end %>
The link_to
helper takes an optional block for the element contents which can be used instead of a string.
A cleaner solution though is to write a helper method:
# app/helpers/movies_helper.rb
module MoviesHelper
# Gives a link for columns in a table that can be used to sort the movies
# will add an icon if the link is "active"
# @param name String
# @param column [Symbol|String]
# @example
# sortable_link_to_movies("Critic rating", "critic_rating")
# @return [ActiveSupport::SafeBuffer]
# <a href="/movies?sort=critic_rating>Critic rating</a>
# <a href="/movies?sort=critic_rating>Critic rating <i ></i></a>
def sortable_link_to_movies(name, column, **opts)
link_to movies_path(sort: "title", **opts) do
# concat is needed to write to the text buffer of the helper
concat name
if column.to_s == params[:sort]
concat tag.i class: "chevron up icon"
end
end
end
end
<%= sortable_link_to_movies "Title", :title %>
<%= sortable_link_to_movies "Release Date", :release_date %>
This lets you test the method in isolation.