Path helpers generate paths with dots instead of slashes - ruby-on-rails

In my routes.rb I have the following:
resources :message_threads
When I call:
message_threads_path(1)
I get:
/message_threads.1
Why is this? My other resources work fine. Am I not pluralizing this correctly or something?

Yes, this is a pluralization error.
By passing the ID 1, I assume that you wish to display a single record.
So you need to use the singular 'message_thread':
message_thread_path(1)
Which will yield:
http://localhost:3000/message_threads/1

Sometimes this also is when you don't provide an :as parameter in your route:
delete "delete/:id" => "home#delete"
Changed to:
delete "delete/:id" => "home#delete", as: :delete
(ignore the odd example, just happened to be something we just ran into for an internal app we're building)

Other folks that land here might be in this situation:
If you have a singular resource declared in your routes.rb:
resource :map
You don't need to pass an object to map_path. Attempting to call map_path(map) will result in similar behavior (i.e. a URL like map.12).

Related

Custom route yields dot instead of '?id='

I am adding a custon new action for my rails app by adding the following to my routes.rb:
resources :adventures do
member do
match :upvote, via: [:post, :delete]
match :downvote, via: [:post, :delete]
end
get 'seed', on: :new
end
(you can ignore the voting piece, just wanted to show you the whole block)
upvote_adventure POST|DELETE /adventures/:id/upvote(.:format) adventures#upvote
downvote_adventure POST|DELETE /adventures/:id/downvote(.:format) adventures#downvote
seed_new_adventure GET /adventures/new/seed(.:format) adventures#seed
adventures GET /adventures(.:format) adventures#index
POST /adventures(.:format) adventures#create
new_adventure GET /adventures/new(.:format) adventures#new
edit_adventure GET /adventures/:id/edit(.:format) adventures#edit
adventure GET /adventures/:id(.:format) adventures#show
PATCH /adventures/:id(.:format) adventures#update
PUT /adventures/:id(.:format) adventures#update
DELETE /adventures/:id(.:format) adventures#destroy
but this:
seed_new_adventure_path(#adventure_collection.id)
generates this:
http://localhost:3000/adventures/new/seed.6
instead of this:
http://localhost:3000/adventures/new/seed?id=6
I read a lot of posts with people getting dots instead of slashes, but none with adding a an additional new action. Am I doing something wrong, or do I need to add something more?
EDIT: I did make a mistake and did not mean to plurailze the adventure path (Is how I had it originally). The real problem is that all I needed to do was pass the id as a parameter.
Here is the path I was looking for:
redirect_to seed_new_adventure_path(:id => #adventure_collection.id)
It's because you are using the wrong pluralization.
In your example, you are using:
seed_new_adventures_path(#adventure_collection.id)
But the route is properly described as:
seed_new_adventure_path(#adventure_collection.id)
And will probably work fine and be more readable as:
seed_new_adventure_path(#adventure_collection)
Routes
Although Brad Werth is correct (your route pluralization is incorrect), the big problem you have is what you're trying to achieve.
You have specified the following link:
domain.com/adventure/new/seed
This is a get request with no other parameters present. I don't understand why you're passing an object to this route? This is why you're receiving the .6 problem (because Rails cannot build the routes), instead of getting /6
After thinking about what you're trying to do, and I believe you can fix it as follows:
#config/routes.rb
resources :adventures do
...
get "seed(/:id)", on: :new #-> domain.com/adventures/new/seed/6
end
OK, so in order to get this:
http://localhost:3000/adventures/new/seed?id=7
I need to pass a parameter to the link like this:
seed_new_adventure_path(:id => #adventure_collection.id)
I just forgot how to pass parameters!

Rails route shows in rake, responds in console,but browser shows undefined method?

I cannot figure out why this route is not working. I have defined it, and it seems that it works everywhere, except for in the browser. I've attached screenshots with the relevant information.
The route for reports_path is showing undefined in the browser, but everywhere else it seems that it's working. What could be causing this?
rake routes shows reports_path, don't use path when naming you routes, you have one more named with path reports_selling_agent_performance_path, remove the path.
in this case:
match 'reports', to: 'reports#index', as: :reports
or
match 'reports', to: 'reports#index'
will work too, you use as: key only if you want to rename the path name that you'll use in code, for example:
match 'my_long_very_long_reports', to: 'reports#index', as: :reports
and you'll use reports_path in code instead of my_long_very_long_reports_path. Or in cases where you use keys like :id or others:
match 'my_reports/:id', to: 'reports#index', as: :reports
where :id will be id of the user for example that you'll send as params[:id]
In your routes file, try changing as: :reports_path to as: :reports otherwise I think you'll need to use reports_path_path in your view.

Adding a record's attribute to the URL before the ID

I'm trying to add a specific attribute of a record in Rails to the URL from something like:
domain.com/share/5
(where 5 is the record ID) to something like:
domain.com/share/johnsmith/5
where johnsmith is stored in record 5. I'm alternating between these two routes to no success:
get "/share/:name/:id" => "share#show"
resources :share, :only => [:show]
And between these two methods:
share_path(doc.user.name, doc)
share_path(doc)
The show method in the ShareController is pretty standard.
The problem:
Using share_path(doc.user.name, doc) in the view generates a link to /share/johnsmith.5, instead of /share/johnsmith/5.
get "/share/:name/:id" => "share#show" should do the job. But you may have to look at the order of routes in routes.rb, maybe Rails took the wrong route?
Best tip to look at what's happening:
Call the URL in your browser (or using curl or whatever) and then look into your console where your started rails s (or rails server).
There you should see something like this:
Processing by ShareController#show
Parameters: {"id"=>"5", "name"=>"johnsmith"}
Concerning the path methods:
Simply use rake routes, it will tell you which path methods are available.
No idea what happened but it resolved itself with this:
get "/share/:name/:id" => "share#show", :as => :share
share_path(doc.user.name, doc)
I do not get the . and / issue at all. I restarted everything and it was gone.

Rails simple routing issue

I have a users_controller. I've created a portfolios_controller which I would like to act similarly to the users_controller; so GETing /portfolios/10 would actually pull the user with an id of 10. I'm not quite sure how to set up my routes for this. Here's what I have right now in routes.rb:
get "portfolios/show"
resources :users
I got the following error when trying to access /portfolios/10: The action '10' could not be found for PortfoliosController.
Thoughts?
I would try a match statement with an :id parameter instead:
match "/portfolio/:id" => "portfolios#show"
Then you will have access to params[:id] in that action.

A custom route along with resource routes

I have setup a custom route, and it seems to work. However, I also have a resources routes as well for the same controller. I think I am just doing something wrong, but I can't tell what it is. I am honestly hacking together routes since I am still a bit confused on how to set them up and when to use what method.
Here are my routes I am dealing with right now.
resources :shows
match "shows/:country" => "shows#index"
The routes like the are the resources :shows works just fine, but not the match. If I flip them the match route works fine, but the resources :shows doesn't.
Should I do this as a namespaced route? I am not exactly sure what I should do. What I am trying to accomplish is something like this.
http://site.com/shows/canada
That will return all Candian shows.
Any help is appreciated.
What you probably want to do is use constraints, or maybe even a custom constraints class. Here's a rough start that I haven't tested and am unsure if it would work:
resources :shows, :constraints => { :id => /[0-9]+/ }
match "shows/:country" => "shows#index", :constraints => { :country => /[a-z]+/ }
Note that typically this would be done via a get query parameter, e.g. http://example.com/shows?country=canada, which would already go to your shows#index action and have params[:country] set to "canada".
You may be getting bitten by the default route which expects /{controller}/{action} and routes accordingly. Try removing the default route. You will have to make sure to declare all of your routes, but the result is a more predictable set of routes for your app.

Resources