I am starting to learn Rails and I am facing an issue which I suppose is very simple but I have not been able to find an answer.
I have a catalog of movies and the index page displays it showing several columns and I need to make two of them a link. This link will re-display the index page again but sorted by the selected criteria.
So far I have only added one link as follows:
%th= link_to 'Movie Title', root_path
But I am not able to send a URL parameter so I can get it in the controller and perform the sort. The actual controller is as follows:
def index
@movies = Movie.all
end
I guess that, if I can get a parameter in the controller then using an "if" statement would do the job. I imagine an URL like this, where "1" means to sort by the first criteria:
http://www.mysite/1
I saw a solution like this but I guess it is not a good choice. Please advice.
<%= link_to "Link Title", something__path(:param1 => "value1", :param2 => "value2") %>
I will very much appreciate any suggestions on how to modify the view and the controller. I have googled several solutions but I am having a hard time understanding the solutions. Maybe there is a better approach to achieve this. If so, then I am ready to listen.
Respectfully,
Jorge Maldonado
This comes down to RESTful path design. It really depends on the kind of field that you're trying to pass to the controller and represent in the URL.
It's important to think of paths as access routes to resources .
Generally speaking, there are two ways to represent the data that you want:
/path/to/resource/:resourceId
. Use this format to represent properties of the resource itself.
/path/to/resource?queryKey=queryVal
. Use this format for metadata and operations on data.
Your initial guess is actually pretty close. What you'll want is something like this instead:
In your controller:
movie = Movie.find(params[:id])
In your view:
<%= link_to 'View Movie', movie %>
Under the hood, Rails is performing some magic that turns this into something that looks fairly similar to your code in the question. It's best to let Rails perform this magic itself though, as it makes changing things later easier.
Also, just to be clear, using path variables (instead of query params) is the best approach for your situation. You can read more on routing in the docs here: http://guides.rubyonrails.org/routing.html
Answering this (I don't have enough rep to comment yet):
I appreciate your response. It works fine. I still have one question. What does it mean a link like this? What is the last parameter (
:id
) used for?link_to "Movie Title", movies_path(:sort => "title"), :id => "title_header"
On link_to
tags, :id
adds an id
field to the generated HTML tag.
This: link_to "Articles", articles_path, id: "news", class: "article"
Generates: <a href="/articles" class="article" id="news">Articles</a>
See the Rails docs here: http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to
(Search for "Classes and ids for CSS are easy to produce:")
What you can do is add the params as you mentioned above. Than in your controller you can do
def index
if params[:param_1] == "param_one"
@movies = Movie.where(id: 'param_one')
else
@movies = Movie.all
end
end
etc. Your solution could like like this =link_to 'xxx', movies_path(:param_one=> "p1", :param_two=>"p2") Will call the index action of movies_controller.rb.
I'd send them in the query string.
For example, taking an URL with a query string such as: www.exmaple.com/resource_name/?sortBy=name
The params
hash contains: "{"filterBy"=>"name", "controller"=>"resource_name", "action"=>"index", "sortBy"=>"name"}"
It's now easy to know by what to sort.
Make sure you don't directly inject that value in an SQL query to avoid SQL injections. Maybe use a switch statement for example.
If you don't like the query string approach (there is no reasons, really, but that's up to you), that a look at what the Rails routing mechanism has to offer.
References:
http://guides.rubyonrails.org/routing.html#the-query-string http://guides.rubyonrails.org/routing.html#non-resourceful-routes
The link implementation is good, I don't see anything bad about it
<%= link_to "Link Title", some_url_helper_path(:param1 => "value1", :param2 => "value2") %>
From the controller's perspective, here are some options on how to filter the data:
# On /users?query=Bob&page=2
>> request.params
=> {"page"=>"2", "query"=>"Bob", "controller"=>"users", "action"=>"index"}
>> request.query_parameters
=> {"page"=>"2", "query"=>"Bob"}
>> request.path_parameters
=> {:controller=>"users", :action=>"index"}
Then you can filter and sanitize the parameters and pass them to the .where()
method.
https://github.com/chrisfrank/rack-reducer
GET /artists #=> all artists
GET /artists?name=blake #=> artists named 'blake'
GET /artists?genre=electronic&name=blake #=> electronic artists named 'blake'
Controller:
# app/controllers/artists_controller.rb
class ArtistsController < ApplicationController
# Step 1: Instantiate a reducer
ArtistReducer = Rack::Reducer.new(
Artist.all,
->(name:) { where('lower(name) like ?', "%#{name.downcase}%") },
->(genre:) { where(genre: genre) },
)
# Step 2: Apply the reducer to incoming requests
def index
@artists = ArtistReducer.apply(params)
render json: @artists
end
end
https://github.com/plataformatec/has_scope - you can read more about it here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.