Rails 5.1 Route Constraint Not Passing Params - ruby-on-rails

Im having an issue after updating to Rails 5.1 with a route constraint.
Basically my route is matching, but no params are being passed through to the controller action. This code has been working for a while, but now it doesn't and im kind of stuck as to why.
Hitting the URL
localhost:3000/?edd_action=activate_license&item_name=ProductA&license=123
Route
get '/' => 'api/v1/legacy_licenses#activate', constraints: { query_string: /edd_action=activate_license/ }
My action code looks like
def load_license_key
if params[:license]
...
end
end
The problem is the params hash never picks up the license param, or the item name one for that matter.
If I inspect the request.query_string on that action all I see is "edd_action=activate_license" so I don't know where the rest of the params are going.
Can anyone help? Changing the URL params isn't an option as its only like this to integrate with legacy software.

Related

Rails routes and querystring

I am having troubles trying to define the correct route for a query coming from ember. The request appears like this:
GET "/users?id=1011
No matter what I try I always have the request forwarded to the index action, while it is intended for the show action.
I have tried many things, like
get "/users?id=", to: redirect('/users')
but nothing seems to work.
Can anyone explain to me what can I do and most important the reason behind it?
Thank you very much for your time!
GET /users?id=1011 always goes to index because Rails just sees the route as GET /users. The question mark denotes a parameter, which isn't part of any of your defined routes.
You can modify your index method to interpret the param, something like:
def index
if params[:id]
# call show, do something, whatever
else
# regular index action
end
end
In the case of retrieving just one user, it would be more common to route this to your show action as you originally intended. To accomplish this, do not pass the id as a query param, but instead as a slug segment /users/1011, which you can accomplish by declaring the following in your routes.rb:
get '/users/:id', to: 'users#show'
If you want to go full tilt then you might as well just declare users as a resource like so:
resources :users
Which will automatically wire up your index, show, update, destroy, etc. Throw Active Model Serializers in the mix and you can have Ember Data start talking to your API nearly "out of the box".

Rails routing, not a supported controller name error

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.

Create a routes to a controller without model with a /id

I have product with a foreign collection_id key
I want to pass an id to a controller.
To do so i have the following routes for my controller :
controller :magasin do
get "magasin" => "magasin#index"
end
The only view in my controller is magasin/index.html.erb
The link to magasin is link_to collection.nom, magasin_path(collection)
This kind of syntax usually works in controllers with models. Here my link is : http://localhost:3000/magasin.2 instead of http://localhost:3000/magasin/2
Later on i will need to call the same view with product_kind_id instead of collection_id and i will add sort by name/price ....
How can i have the ID as a normal argument (/:id)instead of a type(.id)?
A popular URL schema to follow is RESTful routing. Rails has this built-in and will set it up for you if you initialize your resource via rails generate scaffold Magasin nom:string.
If you put resources :magasins in your routing file, it will route /magasins to MagasinsController#index and /magasins/1 to MagasinsController#show with params[:id] set to "1". It will also set up a few other routes that will be useful in the future but for now will just raise an action not found exception.
You don't want to use the dot as an argument delimiter, since Rails places what comes after the dot in the request.format method or just in params[:format] (ordinarily accessed through the respond_to method that comes with the generated scaffolds). Save that dot for later when you are working on delivering alternative display formats like XML and JSON.
I realize I've said a lot in a small space, so feel free to ask any follow up questions once you've consulted the Rails Guide on the issue, and I'll be very glad to help!

How to map non-REST URLS to REST ones?

I have a small rails app that has default scaffold generated routes eg. /stadia/1.xml. However I have to support legacy client app that can't construct such URLs correctly. What I need to do is to map URL in the form:
/stadia?id=1?format=xml to /stadia/1.xml
Or even something like:
/myApp?model=<model_name>?id=<id>?format=xml to /<model_name/<id>.xml
Is it possible to craft appropriate route in Rails?
I don't have good answer for this. What I would do is change first part of url to /stadia_legacy for legacy urls or change first part of urls for RESTful routes.
Then you can map in routes:
map.stadia_legacy :stadia_legacy, :controller => 'stadias', :action => 'please_redirect_me'
Then in stadias controller in action please_redirect_me you can check all params (they are availble in params hash: params[:id], params[:format] etc.) and redirect to correct url. Or you can write all routes manualy to correct controller and action.
What if you do some url rewrite in apache ?
I had a similar question. No answers so far, so it seems routes.rb config doesn't offer an easy way of doing this (routing based on query parameters), which I find surprising actually.
So an ugly workaround would be to have a 'myApp' default route, and then have a special redirecting controller which would look at the query params (because in controllers you do have access to that) and redirect accordingly.

Testing GET in a rails controller

I have a feeling I'm just doing something wrong syntactically but it's surprisingly difficult to Google "GET" so I was hoping someone here might know the answer to this.
I'm trying to test a Rails controller from an RSpec test. I'm following an example I found here - http://www.elevatedrails.com/articles/2007/09/10/testing-controllers-with-rspec/ but I'm stuck on the actual execution of the method I'm testing.
I'm doing a GET request where as the post above does a POST. I'm passing in 2 parameters manufacturer and model.
My URL will ideally look something like http://mysite.com/Products/index/Manufacturer/ModelName
I can't figure out the syntax for the get request call in the rest. Right now I have
get :index, :manufacturer=>#manufacturer, :modelName=>#modelName
and I get back
ArgumentError in 'ProductController Find a valid product should retrieve the product'
wrong number of arguments (0 for 2)
Any thoughts?
edit: It should be noted #manufacturer and #modelName are defined in before(:each)
As i suspected this was me being green to rails programming.
I was defining the controller method as
def index(manufacturer, modelName)
When really i needed to use the params hash to access the attributes. I then had to define a custom route as id is the only parameter expected to be passed into a controller method by default.
once i did that i changed the spec to read
get :index, {:manufacturer=>#manufacturer, :modelName=>#modelName}
and it worked.
Thanks for the comments everyone.

Resources