Ruby on Rails routing for variable controller - ruby-on-rails

I have a URL I want to be able to redirect to.
Something similar to:
"http://localhost:3000/username/admin/page".
I have a match in routes.rb as:
match ':account/admin/:page' => "admin#index"
I have redirect code:
redirect_to :controller => account.username, :action=>"admin", :page=>"index"
This, however comes up with a routing error:
No route matches {:action=>"admin", :controller=>"sdunn", :page=>"index"}
I know what I have done is wrong, but how can I fix this?
Many thanks.

Route is expecting 2 parameters, first one is :account, second is :page, i think you are only passing :page. I would add :as => 'some_name' to your route and then use _path :
routes.rb
match ':account/admin/:page' => "admin#index", :as => 'my_route'
controller:
redirect_to my_route_path(#user, #page)
my_route_path could be something different depending on your exact route file, so use
rake routes | grep my_route
to see exact name, then add _path to the end.

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

What does ":root" mean in the output of rake routes?

When I run
rake routes
I see the following:
POST /articles/:article_id/comments(.:format) {:action=>"create", :controller=>"articles/comments"}
This makes perfect sense. It means if I make a post request to a url of the form /articles/1234/comments, it runs the create action of the controller in articles/comments_controller.rb with the id paramater set as 1234.
But then I see this line also:
/article/:id/:action {:root=>"article", :controller=>"article/article", :title=>"Article"}
And I'm not sure what the ":root" means. Can someone please explain?
EDIT:
I'm using Rails 2.3.18.
Here is the relevant line in the routes.rb file
#routes.rb
map.connect '/article/:id/:action', :controller => 'article/article', :root => 'article', :title => 'Article'
Like :title, it's just another key,value that gets merged into the params hash.
From http://rubydoc.info/docs/rails/2.3.8/ActionController/Routing ( Defaults routes and default parameters)
More formally, you can include arbitrary parameters in the route,
thus:
map.connect ':controller/:action/:id', :action => 'show', :page =>
'Dashboard'
This will pass the :page parameter to all incoming
requests that match this route.
It doesn't have any additional meaning in Rails. My guess is that your app is using it for breadcrumbs or something similar.

Rails 3.2.13 recognize_path returns routing error for constraints

I have two paths in my routes, same path pointing to the different controller and action
match '/:id' => 'users#show', :as => 'user', :constraints => UserConstraint
match '/:id' => 'customers#show', :as => 'customer'
My constraint class has the following matches? method
def self.matches?(request)
return User.exists?(request.path_parameters[:id])
end
this works fine when i call the urls in my browser. however, this does not work for recognize_path method.
Rails.application.routes.recognize_path("/trump", {:method => :get})
returns a routing error (no route matches) whereas works when called in browser as it is appropriately routed.
a user with :id => trump exists.
how do i get recognize_path method to return the path details?
Apparently, it's a bug in Rails, see:
https://github.com/rails/rails/issues/8679

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)

Rails URL question

If I have a Users model, and then an individual user, say, person1, is there a way to have the url: www.myapp.com/person1 show what www.myapp.com/users/person1 would? What would that be called?
Thank you!
You should define a route in your routes.rb file:
match "/:user" => "users#show"
and you'll get the username given in params[:user]. But you need to know that this kind of route could override other routes defined, because it will match any string, so you should at least define some constraints on the username.
For example if your usernames matches a regexp you could define it as a constraint
match "/:user" => "users#show", :constraints => { :user => /some-regexp/ }
and don't forget to set this route as the last one in your routes file, otherwise it will clash for sure with other routes.
Read this for full reference
add "two" routes for the same thing to your app.
# Shorter url to show store items by tags
map.connect '/s/tags',
:controller => 'music',
:action => 'show_by_tags'
map.connect '/music/s/tags',
:controller => 'music',
:action => 'show_by_tags'

Resources