Cant create a link to named routes - ruby-on-rails

I want to create a link to a named route
My routes.db have the following rule
match '/tablero', to: 'tablero#index',via: 'get' , as: 'tablero_main'
I can see the route using rake routes
tablero_main GET /tablero(.:format) tablero#index
But when i use the link_to as follows i get the "undefined local variable or method `tablero_main'" error.
<%= link_to "Tablero",tablero_main %>
Is there anything else i am missing?

You need to append path to the method name, like so:
<%= link_to "Tablero", tablero_main_path %>

Routes
To help you further, you'll need to also consider the role of resources in your routes
As Rails uses a resourceful routing infrastructure, every route you create should be based around a resource. In your case:
#config/routes.rb
resources :tablero, only: :index #-> domain.com/tablero
Admittedly, this will give you the path tablero_index_path, rather than tablero_main_path, but it ensures your routes are not only DRY, but also extensible. Nothing worse than having 100's of "match routes in a route file.
--
Helpers
After that, remember to use the correct route_path helper:
Each "route" path is basically just a helper method (which builds a URL for you). When using link_to, you need to reference the path helper directly. You didn't do this, which lead Rails to come back with the undefined method error

Related

Error using alias for routes in Ruby on Rails

I have a route with a namespace
namespace :publishers do
resources :authors
get 'books' :to => 'books'
get 'books/custom_report/:id', :to => "curriculos#custom_report"
end
Often I will have to make links in my application and I know than it`s possible to use a alias for routing like this:
<%= link_to "Books", publishers_books_path %>
I call that publishers_books_path a alias route, does this is the correct name?
Furthermore, I still not able to understand the logic with this alias naming because i can`t use for a new or a custom action like this
link_to 'Show the report', publishers_books_custom_report_path(params[:id])
I'm always get a error of undefined_method for publishers_books_custom_report_path
So there`s some questions
First of all whats it`s the correct name of this feature in RoR?
How I can use the custom_report as aliases to link_to? And also if i need to use some basic operations like new, update, insert?
Can someone give me the link to the documentation to really understant that feature?
First of all whats it`s the correct name of this feature in RoR?
The docs use "path helper" and "named route helpers" interchangeably.
How I can use the custom_report as aliases to link_to?
Use rails route or visit /rails/info/routes in your dev server to get a list of all your routes, their helpers, and controller actions.
Apparently it is publishers_path which doesn't seem right. You can fix this with an as.
get 'books/custom_report/:id', to: "curriculos#custom_report", as: :books_custom_report
And also if i need to use some basic operations like new, update,
insert?
A get declares just that one specific route. If you need all the operations on a model, declare it as a resource.
namespace :publishers do
resource :authors
resource :books
get 'books/custom_report/:id', to: "curriculos#custom_report", as: :books_custom_report
end
Can someone give me the link to the documentation to really understand that feature?
Rails Routing From The Outside In.

Including attributes in custom Rails routes

I hope the title is not to misleading, as I don't know a better title for the problem I'm working on:
I have a doctor which belongs to location and specialty. I'd like to route to show action of the doc controller like this:
/dentist/berlin/7
I defined my routes like this:
get ':specialty/:location/:id', to: 'docs#show'
And in my views create the following url to link to the show action of the doc controller:
<%= link_to doc.name, "#{doc.specialty.name}/#{doc.location.name}/#{doc.id}" %>
Is this a good solution to the problem? If not, is there a cleaner way to construct urls like this possibly using resources? What the heck is the name for a this problem?
Thank your very much for your help in advance.
For references, you should have a look at this page (especially the end of section 2.6)
If it is only for a single route, it's okay as you did. But then if you want to have more than one route (like /dentist/berlin/7, /dentist/berlin/7/make_appointment, etc.) you might want to structure a bit more your routes so as to take advantage of rails resources.
For example, instead of
get ':specialty/:location/:id', to: 'doctors#show'
get ':specialty/:location/:id/appointment', to: 'doctors#new_appointment'
post ':specialty/:location/:id/appointment', to: 'doctors#post_appointment'
You could have something like this (the code is almost equivalent, see explanation below)
resources :doctors, path: '/:specialty/:location', only: [:show] do
member do
get 'new_appointment'
post 'create_appointment'
end
end
Explanation
resources will generate the RESTful routes (index, show, edit, new, create, destroy) for the specified controller (doctors_controller I assume)
The 'only' means you don't want to add all the RESTful routes, just the ones specified
Then you want to add member actions, ie. actions that can be executed on a particular item of the collection. You can chose different syntaxes
resources :doctors do
member do
# Everything here will have the prefix /:id so the action applies to a particular item
end
end
# OR
resources :doctors do
get 'new_appointement', on: :member
end
By default, the controller action is the same as the path name you give, but you can also override it
member do
get 'appointment', action: 'new_appointment'
post 'appointment', action: 'post_appointment'
end
Rails has some wonderful helpers when it comes to routing !
The correct approach is to give your route a name, like this:
get ':specialty/:location/:id', to: 'docs#show', as: 'docs_show'
Then you can use it like this:
<%= link_to doc.name, docs_show_path(doc.specialty.name, doc.location.name, doc.id) %>
Note 1:
Rails appends _path at the end of the route names you define.
Note 2:
You can see all the available named routes by executing rake routes.

Rails same named route but with parameter raises an error

As of Rails 4.2, I cannot do the following:
get 'profile', to: 'profile#index', as: 'profile'
get 'profile/:slug', to: 'profile#show', as: 'profile'
because it will raise error saying route is already defined. Why is that? Obviously profile_path and profile_path(User.last.slug) are not the same, and there should be no difficulty differentiating the two even if they happen to share the same base name (You check if a param is passed).
Thoughts?
In rails, the helper names for different routes should be different. And hence, as you rightly understood, you will receive an error if you use the same helper name (ie as: 'profile' in your case) for two different routes.
This restriction in Rails helps maintain sanity in your routes.rb file as well as in your application. For instance consider two methods for a controller:
class XyzController < ApplicationController
def method_a(param1)
end
def method_b(param1)
end
end
In your routes file if there was no restriction of keeping helper names different, you could have used :
get 'xyz/method_a', to: 'profile#method_a', as: 'profile_method'
get 'xyz/method_b', to: 'profile#method_b', as: 'profile_method'
Correspondingly in your view file:
link_to 'link_1', profile_method_path('param1') #intended to route for method_a
link_to 'link_2', profile_method_path('param2') #intended to route for method_b
As obvious, in the view file, not only is it difficult to make out which route is intended for which method, its also not possible to route to any other controller method using the helper 'profile_method' except the method that is first to use this helper in your routes.rb file (as routes are read sequentially).
Hope this helps :)
For both routes you specified as: 'profile' and that's your problem here. Besides that, use pluralized route names for #index action, e.g:
get 'profiles', to: 'profile#index'

What does xxxx_path mean in ruby on rails

I try to add new controller and model use name foo and foos_controller, hope foos_path can redirect. Doesn't work.
A origin code here (working):
href="<%= contacts_path %>"
After I add new controller and model follow name convention I try use the same (Not working):
href="<%= foos_path %>"
And this contacts_path is not defined anywhere else in rb project.
what does xxxx_path mean and how to use it?
Rails follows convention to handle roots of application
when we execute this command
rails g scaffold foo
it generates routes along with your model, controller and views.
it generates a line in routes.rb as
resources :foo
this line makes you access all the actions of your controller
for example:
foos_path: # redirects you to the index page of your foos controller
new_foo_path: # redirects you to the create page of your foos controller etc.,
please go through this link for reference: http://guides.rubyonrails.org/routing.html
If you go to your terminal and type rake routes, it will list your currently defined routes. On the left side you'll have their prefix. For example, contacts might route to the index action in ContactsController.
The path suffix is a way of referring to those routes inside your code.
If foos_path is giving you an error, that means you either have not yet defined that route for the resource, or you have but it is called something else (if you defined it manually with the as: option).
More info can be found in the Rails Guide for Routing.
You'll be best reading up on this documentation
Path Helpers
Basically, the path_helpers of Rails are designed to help you define routes for your links etc in the most efficient way possible.
The bottom line is the path helper will take routes defined in your config/routes.rb and then allow you to call them dynamically - IE:
#config/routes.rb
resources :photos #-> photos_path
The path names are typically from your controllers, allowing you to route to the various actions inside them. As Rails is built around being a resourceful structure, it will by default create routes for the "standard" controller actions:
link_to
In order to use the path helpers effectively, you'll be best using the rake routes command in cmd, or by simply typing an invalid url into your app's address bar
I notice you're using the standard HTML <a href=""> tag in your question. You'll be much better suited to using the link_to helper of Rails:
<%= link_to "text", your_path %>

In nested route, how is :format set to nil?

I have the following in my routes.rb:
resources :users do
resources :decisions
end
/users/new works fine, but /users/:id/decisions/new gives me:
No route matches {:controller=>"decisions", :format=>nil}
<%= link_to "New decision," new_user_decision_path(#user) %> gives me the same error.
I've looked in my rake routes and the action and the helper are listed. All of the actions listed have a (.:format) suffix option, but I don't understand how all of my DecisionsController actions are working fine without a format option except 'new'.
How is :format set to nil and what is its default?
it looks like you used a singular decision in your url when it should be decisions. Your url should be /users/1/decisions/new.
However, you should be using a named route to stop this from happening. You should see something like new_user_decision via rake routes. You can then use the new_user_decision_path for all of your links.

Resources