Getting Routing Error(Route doesn't match) - ruby-on-rails

I am trying to update multi-select list on change but I am getting a routing error.
I call this with an onchange event $.post("/levels/category_lists_for_level"
I have an action called category_lists_for_level in a controller called level.
My routes file looks like this.
match '/levels/category_lists_for_level/:id' => 'levels#category_lists_for_level'
resources :levels
resources :levels , :collection => {:category_lists_for_level => :get}
What am I doing wrong here? I never had any problem in Rails 2, all I used to add the collection.

It is a bit hard to say exactly what you need since as others have said you are missing some info, but you have a few apparent things going on here:
You are duplicating routes
You have the route set on a collection and a member
You are allowing multiple requests types (get and post) to access this route.
If you would like to have this operate on a collection you just need:
resources :levels do
post "category_lists_for_level", :on => :collection
end
or on a member:
resources :level do
get "category_lists_for_level", :on => :member
end
This will reduce your routes. Just use rake routes | grep level to get the routes for this controller.
Take a look at this for some more info.

Related

Is it possible to have same routes with different show action in rails?

I am trying to reach the following url in my rails app:
example.com/user12 # It should show user#show
exmple.com/wordpress # It should show category#show
My solution: (it does not work)
In the routes.rb I have added :path => '' to both categories and users in order to remove the controllers' name from the url.
resources :categories, :path => ''
resources :users, :path => ''
When I run rake routes, I have the following urls"
category GET /:id(.:format) category#show
account GET /:id(.:format) accounts#show
So I assumed that It should be working correctly, but surely not. It only works for category names and for usernames it shows ActiveRecord::RecordNotFound.
I know, my solution is wrong because I am confusing rails route system and because the resources :categories has more priority over resources :users, the category show page works fine.
So Is there any solution to solve an issue like this?
I have finally found the solution with constraints option. This option accepts regular expressions.
resources :categories, :path => '', constraints: { id: /wordpress|php/ }
Every category should be added manually in this way OR (I am not sure) maybe there is a way to list all categories from database automatically.
One way of doing that is to override the default rails routes, to do that remove the resources
I tested and this works
SampleRails4::Application.routes.draw do
get '/user12', to: 'users#show' #=> users/show
get '/wordpress', to: 'category#show' #=> assuming u have a controller and action
end
however then you have to update the rest of your code, Ex: users/show might be expecting the user id as a param read more about rails routing

Route override doubles records

I'd like to override a default path of an Spree/Rails extension.
The extension spree_contact_us defines default route in it's config/routes.rb this way:
Spree::Core::Engine.routes.draw do
resources :contacts,
:controller => 'contact_us/contacts',
:only => [:new, :create]
match 'contact-us' => 'contact_us/contacts#new', :as => :contact_us
end
In the routes table there is just one record for route named contact-us:
contact_us /contact-us(.:format) spree/contact_us/contacts#new
If I pass following override in main application's config/routes.rb to routes.prepend method
Spree::Core::Engine.routes.prepend do
match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us
end
rake routes displays routes to a new named path twice, when passed to routes.append even three times:
contact_us /napiste-nam(.:format) spree/contact_us/contacts#new
contact_us /napiste-nam(.:format) spree/contact_us/contacts#new
Can anybody explain this behaviour ?
The problem here is that you will be creating an ambiguous named route :contact_us which when referenced by contact_us_path will return the path for the last entry in routes because you are redefining it.
The duplication does seem strange but I have not looked at how spree handles these things.
In order to avoid this you could rename the secondary route such as
Spree::Core::Engine.routes.append do
match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us_czech
end
This should create 2 routes in which you could use contact_us_path and contact_us_czech_path which will both lead to the same place. then create a method to determine which to use.
Or just add the new route directly into the spree routing tables as (PROBABLY NOT VALID DUE TO CALL TO routes_reloader in Spree Core.
match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us
match 'contact_us' => 'contact_us/contacts#new', :as => :contact_us
Just remember that this means that contact_us_path with always reference the second route.
Edit
It seems Spree builds the default routes and then reloads them after initializing as is stated in the code
# We need to reload the routes here due to how Spree sets them up.
# The different facets of Spree (backend, frontend, etc.) append/prepend
# routes to Core *after* Core has been loaded.
#
# So we wait until after initialization is complete to do one final reload.
# This then makes the appended/prepended routes available to the application.
config.after_initialize do
Rails.application.routes_reloader.reload!
end
I believe this is causing the named route :contact_us to be routed to it's defined route meaning that you defined it as contact_us and then redefined it as napiste-nam and since a variable can have only 1 value it held on to the second one on reload!. Due to this fact I am not sure you can do this directly through Spree.
Using
Spree::Core::Engine.routes.draw
instead of
Spree::Core::Engine.routes.prepend
solved the routes duplication problem for me.

Ruby on Rails multiple methods per page in routes.rb?

Stupid question... I have two forms with two different functions on one page, my views/projects/new.html.erb file. So far I've only implemented one, with the option to "Create" a new project. I want to add another function to sort the records displayed on the same page, something like:
<%= link_to "Category", { :controller => "projects", :action => "sortTable", :filter => "Category" }, :remote => true %>
--
My routes.rb file:
Docside::Application.routes.draw do
resources :projects
resources :categories
#get "home/index"
root :to => "projects#new"
match 'project/new',:controller=>"projects",:action=>"create"
end
But I'm getting the error "No route matches {:action=>"sortTable", :controller=>"projects"}". When I tried adding " match 'project/new',:controller=>"projects",:action=>"sortTable" " my other function didn't work, and the create function got screwed up. What should I have instead?
Try that:
resources :projects do
collection do
post :sortTable
end
end
And look at this guide
You can only have one route for a given path and method combination. You're trying to define multiple routes on the same path, so only one of these will work (the first one). You should be ok if you use distinct paths for each of these actions (instead of project/new for all of them. Beware of collisions with your existing routes)
You'll also make you life easier if you stick to rails' conventions (and the code will be easier to read if someone else starts working on it). For example resources :projects already creates a route for the create action. Additional actions can be added like so
resources :projects do
collection do
get :sort_table
end
end
Sets up a collection route (ie one that isn't about a specific project) for the sort_table action and sets up a URL helper for you (sort_table_projects_path). There are alternative syntaxes you can use - I encourage you to have a look at the routing guide

Rails 3 Finding the right :id in a controller using a specific route

I have my routes arranged so that when visiting the site the :id is displayed before the slug like so
match "/causes/:id/:slug" => "causes#show", :as => :cause, :via => 'get'
But I also have a nested attribute called "post" that belongs to causes like so
match "/causes/:id/:slug/posts" => "causes#posts", :via => 'get', :as => :posts
When I use this, everything works great for the causes, but not for the posts.
If I use
#post = Post.find(params[:id])
in causes or posts controller it always looks for the ID of the causes, and not the :id of the posts. So if the post :id is 9, and the cause :id is 1, and I use
#post = Post.find(params[:id])
it will always look for post[1] and not 9 or whatever the post id really is.
What am I doing wrong? Is there a way to make this work in the routes, or maybe a different way to find the id of a nested object in the controller?
I need the route to be the way I have it set up, :id/:slug...
rake routes information:
cause GET /causes/:id/:slug(.:format) causes#show
edit_cause GET /causes/:id/:slug/edit(.:format) causes#edit
PUT /causes/:id/:slug(.:format) causes#update
posts GET /causes/:id/:slug/posts(.:format) causes#posts
POST /causes/:id/:slug/posts(.:format)
PUT /causes/:id/:slug/posts(.:format) causes#update_post
DELETE /causes/:id/:slug/posts(.:format) causes#destroy_post
causes GET /causes(.:format) causes#index
POST /causes(.:format) causes#create
Any help would be great.
To solve your immediate problem, you'll want to add something like this to routes.rb
# config/routes.rb
match "/causes/:cause_id/:slug/post/:id" => "causes#update_post", :via => 'put', :as => :update_post
And then you can generate the URL in your views like this...
link_to 'Update this post', update_post_path(#cause, #post)
...and access the parameters in your controller as params[:id] (for the post) and params[:cause_id] (for the cause).
More generally, though, the way you are specifying your routes is pretty cumbersome, and I suspect you're making your life harder than it needs to be. If this were me, I would do something like
# config/routes.rb
resources :causes do
resources :posts
end
This would accomplish something pretty close to what you have now, the main difference being that it wouldn't contain slugs. I'm not sure why you need to have both slugs and IDs, maybe you could just identify your causes by their slugs? Stringex is a good gem for generating slugs, and you can set it so that slugs are guaranteed to be unique.
Here is the section of the Rails guide on nested resources
http://guides.rubyonrails.org/routing.html#nested-resources
And here is a Railscast about using slugs with nested resources
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=comments
Hope this helps.
This is because you're using the id of the cause, and if you're doing /causes/:id/posts shouldn't you be doing #posts = #cause.postsanyway?
I would look into the new router syntax for rails 3 if I were you, as there is a nicer way to nest resources http://guides.rubyonrails.org/routing.html
edit:
use the friendly_id gem and nest your resources, to avoid confusion follow REST best practises that resource in question is at the end so
/causes/:slug/posts/:slug

Routing: prefix item name before controller resources

I am trying to get the following routes to work in my Rails 3 app.
Scenario:
I have the following controllers in my app:
Practices
Doctors
Patients
Prescriptions
Putting up :resources for each of them in routes.rb gives me routes from
example.com/practices
example.com/doctors/1/edit etc
What I'd like to have however is the following resourceful routes, for example:
example.com/james_practice/docs that translates to the doctors controller
example.com/james_practice/awesome_prescriptions that routes to the prescriptions controller etc. etc.
both of these giving me access to :practice name and furthermore route the correct controller with all the helpers like edit_docs_path(doctor) etc.
How would I go about this? I've used
resources :prescriptions, :path => "/:practice/awesome_prescriptions"
but although it showed the correct routes in "rake routes", it still wouldn't work as expected.
I think this is the route you're looking for:
scope :path => ":practice" do
resources :docs, :controller => "doctors"
resources :awesome_prescriptions, :controller => "prescriptions"
end
By the way, you didn't give me the example of Patients, so I didn't put it there.
map.resources is just a pattern, more like a shortcut. If you want to have URLs like in your examples you should use "named routes". A good screencast for Rails 2.x: http://railscasts.com/episodes/34-named-routes
Edit: Read section 3.2 in Rails Tutorial: http://guides.rubyonrails.org/routing.html
p.s. Also you'll face a case where people use "." in their names and it'll cause problems.
Here's my route for "tags"
map.resources :tags, :requirements => { :id => %r([^/;,?]+) }

Resources