Rails routing, not a supported controller name error - ruby-on-rails

I am in the process of learning Rails, I am trying to make a small search functionality, I am setting up the route for this like this:
get 'search?q=:keyword' => 'search?q=#show'
and in the url I am trying to access this using
http://localhost:3000/search?q=test
but this is giving me this error: not a supported controller name.
Youssef

The reason is that you are trying to route with the query string ?= still in the path. Rails is a little smarter than that so the parameters will be passed automatically.
get 'search' => 'search#show'
Will retain the parameters in the redirect without you needing to do anything extra.

Related

Rails routing forcing param to be present

I'm fairly new to ruby api development and have created the below endpoint in my routes.rb
get "/users/active_users/:since"
However, when the param is not given, I want the param to default to a certain value. How do I enforce this? Also, I want to enforce that param be an integer and not alpha/alpha-numeric. Help is appreciated!
get "/users/active_users/:since"
By making this routes its compulsory to give the params[:since] , other wise it will throw back a error not routes matches
So here by i would suggest you to make routes
get "/users/active_users"
Since it's get type request so its won't affect more, you can append params[:since] in query with routes like this:-
/users/active_users?since=1999
And at your controller you will get params[:since] = 1999
So far as i know it can't be enforce routes to accept only integer params but it can be handle at controller side
params[:since].is_a? Integer
=> true
Or
params[:since].to_i

Rails routing sometimes replaces the id in url with id-name. How do I avoid problems?

Generally the url from my report page looks like this:
http://test-account.peter:3000/offices/7/reports/index
However, sometimes it looks like this:
http://test-account.peter:3000/offices/7-peters-office/reports/index
Why does this happen?
It was not really a problem until we changed the controller action from a GET to a POST and renamed it. We had to do this so we could pack more parameters in to the ajax request. Users still have this section of the site bookmarked and it throws errors all day long.
I have tried to redirect the route:
get '/offices/*all/reports/index' => 'offices#show'
get '/offices/:office_id/reports/index' => 'offices#show'
get '/offices/:office_name/reports/index' => 'offices#show'
Is there a way to catch the name? Or do I have to prevent the name from being added to the url in the first place?
In the controller, you would be able to parse the parameter to get just the first character and check if its an integer. However, it would be much better to debug how the parameter is getting assigned to different values and ensure only the id is used. If you're linking to that route in a view, check what is being passed in the link and confirm the value is what you expect it to be.
Rails does routing it does not look in your database for matched data. So without looking at data, your three routes are exactly the same, the variable (office_id & office_name) is just named different. If you get a request on example /offices/:office_name/reports/index, rails will just match the first one since both routes match the request.
You need something in the path that indicates its a name or id. If you will really never have a name and id with the same search, then you could just have one route and try to match a id or name from the DB in the controller.

Rails 3 gives routing error with point in URL

I have a search form written with Rails 3 when I query it everything works fine as long as I do not put a point in my query. Eg:
http://localhost:3000/en/job/search/q/test - WORKS
http://localhost:3000/en/job/search/q/test. - DOES NOT WORK
URL with point at the end gives a
Routing Error: No route matches [GET] "/en/job/search/q/test.
Does anybody know how I can solve this? Thanks.
By default, Rails interprets everything to the right of the decimal as the format. You need to set the :constraints
Here is a good article on the subject: http://coding-journal.com/rails-3-routing-parameters-with-dots/
Here is the reference in the Rails API that should help you resolve your issue:
http://guides.rubyonrails.org/routing.html#specifying-constraints
http://guides.rubyonrails.org/routing.html#dynamic-segments
Since your passing a string in the search as a get request, you might also consider route globbing: http://guides.rubyonrails.org/routing.html#route-globbing
Your route would be something like this:
match ":language/job/search/*query"
and in your controller, you would get the value from the route using the params[] array:
q = params[:query]
Be sure to use best practices when passing this to ActiveRecord to avoid a SQL injection attack.
What #iltempo said.
Also, it would be a good idea to switch your search from using GET requests to POST requests to make all these problems go away.

Resolve Route Server Side in Rails

Just as you figure out the route when the browser hits the webpage in Rails, how would you resolve it on the server side?
For example I want to return a URL to a RESTful resource called Bookmark in an API call and want to return the 'show' action of it, and I know that:
Bookmark id: 12
Then I want to resolve it to a string:
'/bookmarks/edit/12'
so that I can get this from my Model for example.
How would I go about doing this?
Thanks!
Pretty much everywhere in the views/controllers you can use route helpers to DRY up route references.
In models, you'll need to explicitly call the route helper like so.
Rails.application.routes.url_helpers.edit_bookmark_path(id) # => '/bookmarks/12/edit'
When using the default resourceful route generator method in routes.rb like
resource :bookmarks
I'm not sure I understand - your server is the thing that's making all of those routes work - the client's browser isn't figuring out what the route is - you application is doing it.
The paths to your resources are available as helper methods at all times (at least within the controllers, and views). As such, you should return the string as the body of a response in one of your actions, in the controller that's handling your API calls.
Check your rake routes on the command line, and you'll see a list of them. In the case of your example above, it would likely be called edit_bookmark_path(12)

what are the sequence of events that happen when you get a page

Im trying to get my head around the sequence of events that happen between when rails receives a get/post command and the page is served. I was just trying to map out the sequence myself and i realised i dont fully understand myself which scripts is even ran first so I'd like to clear it up in my head.
many thanks
jon
The request goes into the route matcher which parses the URL, parses the config/routes.rb and if the URL matches a route, it looks for a controller file whose name matches the controller part of the URL, (e.g. http://localhost/categories will look for a CategoriesController)
Then, one of two things happen:
If you're using a Rails restful route, the route matcher applies heuristics to figure out which of the 7 actions to call: a GET on a plural last part is mapped to index; a GET mapped to an ID-looking part after the plural is mapped to show (e.g. categories/1 or categories/something or categories/1-something); a POST to a plural last part is mapped to create; a PUT to an ID-looking part after the plural is mapped to update; a DELETE to the same URL is mapped to destroy; new and edit are mapped to GETs for categories/new & categories/edit.
If you have a custom action, you must have a method in your controller object of the same name.
The chosen action is executed and then Rails either renders the template/file/action specified in the render call within the action or it looks for a view file of the same name as the action and that ends with .html.erb (by default) in the app/views/ directory.
Simple.
Rails does quite a lot of things, a good way to get a decent overview is to read the "Action Controller Overview" document at rails guides: http://guides.rubyonrails.org/action_controller_overview.html
The basic structure is:
rack middleware
routing
filters
controller code
rendering
filters
But rails also does many things by itself to the request. It automatically determines what kind of response you want based on your accept headers, and/or if you manually specify which type of response you want with a file ending like /blog/1.xml. Rails also magically creates a nicely formatted params hash, parsing params like user[name]=foo to {:user => {:name => "foo"}}. Rails also has built-in exception handling and some nice stuff to prevent cross site request forgery and much more, so check out the Controller Overview for the lowdown on that.

Resources