Building custom route in rails - ruby-on-rails

I have this route:
put 'workstations' => 'workstation#update'
that I'm intending to match up with this link:
link_to "Update", controller: "workstations", action: "update", :method => :put
but I'm getting this error and I don't know why:
No route matches {:controller=>"workstations", :action=>"update", :method=>:put}
How can I build the route and why isn't what I've specified working?

It might be a spelling error.
You wrote:
put 'workstations' => 'workstation#update'
But the controller name should be plural as in:
put '/workstations' => 'workstations#update'
Also, you can always run rake routes and get the list of generated routes and route names in your app.
EDIT
By the way, you can achieve the same routes generation with the following, more elegant way:
resource :workstations, only: :update

Related

Understanding rails routing that include (=>) and (:as)

While reading about rails routing I found routing that include =>. But I don't understnad what it means. Also I found some routing example with :as. It would be nice if someone explained a little bit about it. I have read rails guide but still I am not quite clear about them.
Please explain what this means
get 'customer_details' => "customers#details"
and
get 'customer_details' => "customers#details", :as => :customerdetails
Each time you define a route, you have to define a controller#action for that route:
#config/routes.rb
get :customer_details => "customers#details"
get :customer_details, to: "customers#details"
get :customer_details, controller: :customers, action: :details
The routing module provides URL rewriting in native Ruby. It's a way to redirect incoming requests to controllers and actions.
The following symbols are special:
:controller maps to your controller name
:action maps to an action with your controllers
Other names simply map to a parameter as in the case of :id.
Using => is simply a shortcut for the to: option...
When a pattern points to an internal route, the route's :action and :controller should be set in options or hash shorthand. Examples:
match 'photos/:id' => 'photos#show', via: :get
match 'photos/:id', to: 'photos#show', via: :get
match 'photos/:id', controller: 'photos', action: 'show', via: :get
In short, it's another way to pass the required "controller#action" arguments to the Rails router.
--
Of course, this is negated by using the resources directive, which sets the controller & actions implicitly:
#config/routes.rb
resources :customers, only: [], path: "" do
get :customer_details, on: :collection #-> url.com/customer_details
end
The routing middleware (ActionDispatch::Routing) takes inbound URL paths, and matches them against your defined routes -- sending the user to the appropriate controller / action.
The entire routing structure (even when you use link_to) depends on having the controller & action set for a route; especially true with a path helper.
Setting as: gives you the ability to explicitly define the name of the path, for example:
#config/routes.rb
get "search/:query", to: "application#search", as: :app_search
... the above will create the helper <%= app_search %>
Update
In response to your comment, you'll want to use either of the following:
#config/routes.rb
get "customers/details", to: "customers#details" #-> url.com/customers/details
- or -
resources :customers do
get :details, on: :collection #-> url.com/customers/details
end
If you're defining a single route, only use symbols if Ruby can interpret that data without any interpolation. For example get :details can be treated as get "details", however get "customers/details" cannot be treated as a symbol.

Rails routes not matching 'new' pattern with RESTFul routes

I got this error:
No route matches {:action=>"show", :controller=>"video_publications", :campaign_id=[...]
With this url:
/campaigns/514be3834413790249000025/video_publications/new
I have this in the routes:
resources :campaigns do
resources :video_publications
end
I got the error when I am redirecting to:
new_campaign_video_publication_path(#campaign)
I am confused, any ideas?
Using:
Rails 3.2.11
Mongoid 3.0.23
The error is not in your new path, but in your show action.
It is complaining about:
:action=>"show", :controller=>"video_publications"
In your code change parts of the code for show action to something like this:
<%= link_to 'Show', campaign_video_publication_path(#campaign, #publication) %>
Add this line of code in the routes.rb
match 'campaigns/:id/video_publications/new' => 'campaigns/video_publications/new',:as => :new_campaign_video_publication

When should I create named routes in Rails?

I'm confused by Rails 3 resource routes. I have following line in my routes.rb
resources :dungeons, only: [ :index, :destroy, :create, :update, :show ]
When I inspect what named routes are create with rake routes, I get:
dungeons GET /dungeons(.:format) dungeons#index
POST /dungeons(.:format) dungeons#create
dungeon GET /dungeons/:id(.:format) dungeons#show
PUT /dungeons/:id(.:format) dungeons#update
DELETE /dungeons/:id(.:format) dungeons#destroy
Why are there only named routes for the routes with a http get method? If I want to create a link to the destroy action, I have to use something like { :action => 'destroy', :method => :delete, :id => dungeon.id } instead of simply destroy_dungeon_path( dungeon ). Is there something wrong with my routes.rb?
Nothing wrong with your routes file. This is the destroy route: dungeon_path(id)
You have to send a DELETE request to trigger it. The show, update and destroy got the same named_route, the only thing what is different is the type of Request (GET for show, PUT for update or DELETE for destroy)
Here everything you need to know routing in Rails3: http://guides.rubyonrails.org/routing.html

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)

Where is this "posts_path" variable defined?

I'm following this tutorial (seems good) for Rails. After I run
ruby script/generate scaffold Post
then this link works in one of the erb files:
<%= link_to "My Blog", posts_path %>
WHY? I've looked for "posts_path" in the whole app and it's nowhere to be found. On the other hand, this
<%= link_to "My Blog", home_path %>
does not work, and it's also a Controller.
Where is the posts_path defined?
posts_path is a named route you get for free from the route that was added by script/generate scaffold. See routes.rb you should see something like this:
map.resources :posts
See the API docs for information on what other named routes you get for free.
Also you can run rake routes and see what all your routes.rb is giving you.
If you want a home_path named route add a line like this to your routes.rb:
map.home '/home', :controller => "home", :action => "index"
I believe that "posts_path" is created dynamically by Rails at runtime. Look at your routes.rb file - Home is probably not defined the same way as Posts. It has nothing to do with you controllers, it's dependent on the route definition.
map.root :controller => "home" would be a shorter way of writing the path to your home directory. This will use / has the home, and not /home. If you still want to use /home (and home_path), map.home 'home', :controller => "home" will do the same thing.
There's a great guide written by Mike Gunderloy about everything there is to know about routing.

Resources