will_paginate and named_routes - ruby-on-rails

I have some problems using will_paginate and named routes.
Here is some code (my site is in Spanish language):
routes.rb
map.animals '/animales/:scope/:id', :controller => :categories, :action => :show
with these routes I generate URLs like:
www.domain.com/animales/mamiferos/perros
but, when pages links are generated I get links like:
www.domain.com/animals/perros?page=2&scope=mamiferos
Why are they like that?
NOTE: I am also using friendly_id.

You need to make sure that there is no matching route before the animals route in the routes.rb file. E.g. the default route map.connect ":controller/:action/:id" and the resource definition map.resources :animals should come after the named animals route.

Related

Named routes inserting a . instead of a /

I've been having trouble with named routes in rails 4 (Named route for non resource nesting).
I've moved onto something else, but still struggling with the same problem of named routes for non resource urls.
This is my route from rake routes:
GET /messages/:id/report/:reply_token(.:format) messages#report
messages POST /messages(.:format) messages#create
and my routes.rb
resources :messages, only: [:create] do
member do
get 'report/:reply_token', :action => 'report'#, :as => :message
end
end
Because of the problem I had in my post linked at the top, I'm trying to get a url to the /messages/:id/report/:reply_token route by doing the following:
"#{messages_url(#message, :host => "localhost:3000")}/report/#{#message.reply_token}"
But it's giving me this:
http://localhost:3000/messages.110/report/6bBw22TdaRYcQ3iVzW1ZwA
Why is there a . between the 'messages' and the '110' (message_id)?
Instead of #message, I've also tried #message.id in the messages_url(). I've also tried this: report_message_path(message_id: #message.id, reply_token: #message.reply_token) but got the same error as in my question linked above. I've also tried message_url() instead but it gives undefined method 'message_url'.
You are mixing up routes. messages_url is to generate a URL for create action which does not have ID in its route. Rails assumes 110 is the format and uses the second route (which is named as messages)
messages POST /messages(.:format)
As a solution, name your route like this and also add show action
resources :messages, only: [:create,:show] do
member do
get 'report/:reply_token', :action => 'report' , :as => :custom_message
end
end
And,
custom_message_url(#message, :host => "localhost:3000")
More about naming routes here.
Answerd here already - Rails _path helper generating path with format not id

How can I guess the route helpers that are created with match in Rails?

I have created a route in the routes.rb file like this:
match ':controller/:action/:id'
I tried invoking add_posts_path() and add_post_path() from my view and in both cases I got similar error messages like this one:
undefined method `add_post_path' for ...
I have tried declaring my match route both before and after the resources :posts declaration.
Are any route helpers created for such a route? I am unsure what helper methods can be used with such a match rule.
You can name routes with :as parameter
match '/foo/bar', to: 'foo#bar', as: 'foo_bar'
and then use foo_bar_path in your view
http://guides.rubyonrails.org/routing.html#naming-routes
If you have resources :posts, you have a helper new_post_path to add new posts. Run rake routes to see your apps routes.
add_post_path does't follow Rails routes convention for resources and if you need it, must add a custom method:
resources :posts do
get :add, :on => :collection
end
You can read more about this in this Rails guide.
When you define match ':controller/:action/:id', you set the format of your app's urls and their params, but this do not magically will define routes helpers.

For arbitrary routes in Rails 3.x, how can I use UrlHelper to access them?

So I have a route in routes.rb like this:
get "customers/:id/payments", :controller=>"customers", :action=>"payments"
What would be the UrlHelper that would generate this, if any, when doing this in a view:
link_to customer.name, customers_payments_path(customer)
(customers_payments_path is not valid)
get "customers/:id/payments", :controller=>"customers", :action=>"payments", :as => 'customer_payments'
http://guides.rubyonrails.org/routing.html#naming-routes
From the above link:
You can specify a name for any route using the :as option.
I like Gazler's answer if it's only a one-off route, but if you've already got resource routes for customers then I would define this route like this:
resources :customers do
member do
get :payments
end
end
This way, you would still have the standard customers_path and customer_path helpers you'd normally get from a resource route, but it would also generate customer_payments_path in a shorter syntax.
You need to add the :as parameter to add a name to the route, so you can access it from a url_helper:
get "confirmations/:code" => "confirmations#show", :as => "show_confirmation"
Then in your views/controllers/tests:
link_to "Confirm", show_confirmation_url(confirmation)

How to change URL in Rails

I have a resource called Book, then I have domains like:
domain.com/books/272
But I want to change it to
domain.com/stories/272
Only for the URL, don't need to change controller, classes etc.
In the routes I have
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
map.root :controller => 'static'
How can I do it? Thanks
In rails 3, I believe you would do the following:
resources :books, :path => 'stories'
Depends really on what you have already.
Use this code to your routes file: (in the case of the original URL of books replaced by stories)
#resource routes
map.resources :books, :as => :stories
#named routes
map.books 'stories/:id'
Without defining routes the only option I can think of - which seems terribly wrong - is to add a new controller which inherits from your books controller. You'd need to go through your application and change the controller name used to generate paths or URLs as seen in the following example:
class BooksController < ApplicationController
class StoriesController < BooksController
Personally, I would recommend you take the time to define your routes but I guess this depends on how large an application you're working with.
This guide will help you understand routing in RoR: http://guides.rubyonrails.org/routing.html
Its called named routes and is done in your config/routes.rb
In your routes file:
map.stories 'stories/:id', :controller => 'books', :action => 'show'
Then in your view you can access this route with:
<%= link_to book.name, stories_path(book) %>
Make sure you change book.name to whatever name you want. also make sure you passing book as a local variable to the routes path.
You can also change the :id to be more SEO friendly with to_param in the respective model.
In your model:
def to_param
"#{id}-#{name.gsub(/\s/, '_').gsub(/[^\w-]/, '').downcase}"
end
Also make sure you replace name with an attribute that the book model actually has.

How do you check the URL Helpers for a Model Resource in Rails?

I'm currently following the Shovell tutorial in the Simply Rails 2 book. On page 168, it mentions URL Helpers for the Story Resource:
stories_path /stories
new_story_path /stories/new
story_path(#story) /stories/1
edit_story_path(#story) /stories/1/edit
The above is then used in the controller:
def create
#story = Story.new(params[:story])
#story.save
redirect_to stories_path
end
My routes.rb:
ActionController::Routing::Routes.draw do |map|
map.resources :stories
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
It looks like stories_path is the url name to /stories. Is that explicitly defined somewhere within my app, I can't seem to grep for that keyword. If not, is there a way that I can check the mapping above from the Rails console or somewhere else? In Django, url names are usually explicitly defined in urls.py, I just can't figure out how the above is being generated. Any documentation and pointers will help.
To get a list of the mapped routes:
rake routes
What map.resources :stories is doing is mapping your RESTful actions (index, show, edit etc.) from the stories_controller.rb to named routes that you can then use for simplicity.
routes.rb includes helpful tips on defining custom routes and it may be worth spending a little bit of time looking at resources in the API to get a better understanding:
http://api.rubyonrails.org/classes/ActionController/Resources.html#M000522
I think checking out the Rails Guides on Routing will help you a lot to understand what's going on
In short, by using the
map.resources :stories
the Router will automatically generate some useful (and RESTful) routes. Their path will take the model name (remember in Rails there is the Convention over Configuration motto), and, by default, will generate routes for all the REST actions.
This routes are available through your controller, views, etc.
If you want to check out which routes are generated from your mappings, you can use the "rake routes" command.
Now, given that, you can also write explicit URLs on your routes.rb file for actions or events that don't quite comply with the REST paradigm.
For that, you can use
map.connect "/some_kind_of_address", :controller => :pages, :action => "something_else"
Or
map.home "/home", :controller => :pages, :action => "home"
The last one will gave you both home_path and home_url routes you can use in your code.

Resources