How to pass and receive parameters in url in Ruby on Rails? - ruby-on-rails

I am new to ruby, i would like to pass parameters in the url and receive it in controller.
I am expecting operation like
www.mysite.com/getuser/id/22
where getuser is the param name and 22 is its value.
Please provide me if there is any useful links that i can refer to.
Thanks in advance

Please read everything in the Rails Guide to Routing. There are two main cases there:
RESTful routes: only use GET, PUT, POST, DELETE. Rails maps that by using the method resources. resources :pages will lead to the following routes (and URLs) automatically:
sites GET /sites(.:format) {:action=>"index", :controller=>"sites"}
POST /sites(.:format) {:action=>"create", :controller=>"sites"}
new_site GET /sites/new(.:format) {:action=>"new", :controller=>"sites"}
edit_site GET /sites/:id/edit(.:format) {:action=>"edit", :controller=>"sites"}
site GET /sites/:id(.:format) {:action=>"show", :controller=>"sites"}
PUT /sites/:id(.:format) {:action=>"update", :controller=>"sites"}
DELETE /sites/:id(.:format) {:action=>"destroy", :controller=>"sites"}
Other routes: There is a rich set of methods you can use in your routes file to add additional routes. But keep in mind: If you just want to address a resource, it is better to stick to restful routes. A typical example is_ match ':controller(/:action(/:id))'. This allows URLs like:
localhost:3000/sites/help: controller == SitesController, action == help
localhost:3000/sites/search/something: controller == SitesController, action == search, parameter in params is something under the key id. So inside the action search, you will find params[:id] bound to "something".

In your config/routes.rb file you write:
resources :users
Then you create the controller:
rails g controller users
Inside your controller file you have something(contrived) there like :
def show
my_id_param = params[:id]
end
When you go to:
www.mysite.com/user/22
my_id_param will be 22
I think rails guides are quite good resource, just google for them, has ton of good info there.

Related

Rails - start your route from second element of the path

Is there a way in rails to start routing from 2nd part of the url path?
for example localhost:3000/tenant_name/posts for resources:posts
tenant_name is a name of the schema in my database.i want switch to respective tenant using the tenant_name.
when i run this now will get No route matches [GET] "/tenant_name/posts"
I need to visit posts even if replace "tenant_name"with any tenant_name.How to do?
Using scope without any options and only a scope name, it will just change the resources path.
scope :sometext_here do
resources :posts
end
This will generate url like -
Prefix Verb URI Pattern Controller#Action
posts GET /sometext_here/posts(.:format) posts#index
POST /sometext_here/posts(.:format) posts#create
post GET /sometext_here/posts/:id(.:format) posts#show
PATCH /sometext_here/posts/:id(.:format) posts#update
PUT /sometext_here/posts/:id(.:format) posts#update
DELETE /sometext_here/posts/:id(.:format) posts#destroy
Alternative way to use it -
get '/:dynamic_text/posts' => 'posts#index', as: :all_posts
So it can be used as
all_posts_path(dynamic_text: "sometext_here")

Why redirecting to #show action without passing the :id param work (in rails)?

I have a simple question about rails.
I followed a tutorial (from CrashLearner).
In that tutorial we have a simple resource message that generates the regular following routes (excerpt from rake routes)
Prefix Verb URI Pattern Controller#Action
messages GET /messages(.:format) messages#index
POST /messages(.:format) messages#create
new_message GET /messages/new(.:format) messages#new
edit_message GET /messages/:id/edit(.:format) messages#edit
message GET /messages/:id(.:format) messages#show
PATCH /messages/:id(.:format) messages#update
PUT /messages/:id(.:format) messages#update
DELETE /messages/:id(.:format) messages#destroy
As I understand the route to get to the show action of this controller is like something /messages/17, I mean we have to put the :id of that particular message we want to view.
So, if I needed to redirect the user to this message view after he modified it (in the #update action) I should use:
redirect_to message_path(17)
But it turns out that omitting this :id actually works great:
redirect_to message_path
Why and how this last one work ?
Since this works from an action that actually received the :id param I suppose that the controller keep it in memory and pass it through by default under the hood when it is missing but I would like to understand where this behavior come from ?
I found nothing in the rails documentation.
Here is the github repository of the tutorial, so the exact specific place of the above line is here in this controller.
And I confirm that this works.
There is also a Comment resource that is nested from the previous Message resource.
As you can see in that controller on the update action, after updating a comment (which is nested within a message) the controller redirects to the message_path but in that case the :id parameter is present through the instance variable #message (and I learned that this works because the object Message respond to an .id method otherwise it should be #message.id)
I supposed that the reason that why here the :id is still passed is because we are in the Comments controller and the :id of another resource could not be passed under the hood, thus why it is explicitely written.
I don't have another explication..
Can anyone explain me why this works ?
I found this in Rails source:
Missing routes keys may be filled in from the current request's
parameters (e.g. +:controller+, +:action+, +:id+ and any other
parameters that are placed in the path).
So here :id exists in the current request params and it's used for this route.
If you define singular resource you will have show action without :id param
http://edgeguides.rubyonrails.org/routing.html#singular-resources

Rails 5 rename single resource route name

I am trying to create a separate :show route, to use route globbing on the :id parameter. For this, I created a resource route without the show route and also a separate show route:
resource :test, except: [:show]
get 'test/*id', to: 'test#show', as: :test
the problem is that I receive the error: You may have defined two routes with the same name using the:asoption, or you may be overriding a route already defined by a resource with the same naming.
If I remove as: :test it works. rails routes shows:
tests POST /tests(.:format)
new_test GET /tests/new(.:format)
edit_test GET /tests/:id/edit(.:format)
test PATCH /tests/:id(.:format) <-- WHY??
DELETE /tests/:id(.:format)
GET /tests/*id(.:format)
as you can see, resources renamed the PATCH route to :test. If I remove that route, the DELETE route is named test, and so on. How can I stop resources from using the test route name specifically? I cannot move my globbing route above the resource block obviously because then all other routes are globbed too.
What I want:
tests POST /tests(.:format)
new_test GET /tests/new(.:format)
edit_test GET /tests/:id/edit(.:format)
PATCH /tests/:id(.:format)
DELETE /tests/:id(.:format)
test GET /tests/*id(.:format)
Rails uses the same prefix (say, in your case "test") for all those four routes[show(GET), update(PUT/PATCH), destroy(DELETE)] and it recognises the different routes with the HTTP Verbs.
I don't understand your problem, but if you look on Rails Guides "Singular Resources" you can see:
Path Controller #Action Used for
GET /geocoder/new geocoders#new return an HTML form for creating the geocoder
POST /geocoder geocoders#create create the new geocoder
GET /geocoder geocoders#show display the one and only geocoder resource
GET /geocoder/edit geocoders#edit return an HTML form for editing the geocoder
PATCH/PUT /geocoder geocoders#update update the one and only geocoder resource
DELETE /geocoder geocoders#destroy delete the geocoder resource
show, create, update and destroy use the same route but with different HTTP verbs. And in your case, test wrote with PATCH verb, because this verb earlier in the table, empty name means that it uses the same name as upper line.
First of all,
test PATCH /tests/:id(.:format) <-- WHY??
DELETE /tests/:id(.:format)
GET /tests/*id(.:format)
Patch is for your Update method routes.
Delete is for destroy method route.
that add by your custom route generated by get 'test/*id', to: 'test#show', as: :test
So, here you can make your show route with different alias. Ex like using as :show_test

Incorrectly routing /index to /show in Rails

There must be an obvious answer to this, but I'm at a loss.
I have a Rails app which tracks sites. For whatever reason, localhost:3000/sites leads to my index page. However, localhost:3000/sites/index leads to my show page.
Why is this?
Below is the routes file:
Rails.application.routes.draw do
resources :sites
Below is the sites controller:
class SitesController < ApplicationController
def index
end
def show
end
end
In views/sites, there is the index.html.erb and show.html.erb files. The former displays at /sites, the latter displays at /sites/index (and /sites/show as one would expect).
Thanks for any help!
UPDATE:
When I rake routes, I get:
Prefix Verb URI Pattern Controller#Action
sites GET /sites(.:format) sites#index
POST /sites(.:format) sites#create
new_site GET /sites/new(.:format) sites#new
edit_site GET /sites/:id/edit(.:format) sites#edit
site GET /sites/:id(.:format) sites#show
PATCH /sites/:id(.:format) sites#update
PUT /sites/:id(.:format) sites#update
DELETE /sites/:id(.:format) sites#destroy
These routes are what one would expect, but I guess I'm just surprised that sites/index presumes index is an :id and therefore routes the request to show.
I suppose I had never explicitly encountered that behavior before.
There are 7 basic actions in a controller by default, only 2 of them are matched by name in the url - (new and edit). These 2 are HTML constructs, they are just a way of rendering a form.
The other 5 (index, show, update, create, destroy) are the more basic routes and do the work to display and modify resources. They are referenced by only two url patterns (the two patterns you mentioned above - eg '/sites' and '/sites/:id'). They are differentiated by the method that goes along with the request: (Patch, Post, Get, Delete). So, "/sites" would be used for create and index. "/sites/:id" would be used for show, destroy, and update.
The action in the controller is not referenced by the url exactly - the url pattern and the request method together are used to call the associated controller method.
In the request "/sites/index", as the string "index" is in the url, the only route that matches is one that has a variable after "/sites/". :id is just a variable, not necessarily an integer. Since the request was a GET, the first (and only) route match is sites#show. "index" will be the value of params[:id] passed into the show action.
This is the way routing works in Rails. Take a look at Rails routing to get a better understanding of how this works. Especially the
Rails resource routing section.
Generally when you setup a resource route as you did the urls would be as follows:
example.com/sites #=> index page
example.com/sites/:id #=> show page. A specific site, where :id would be the unique identifier
# Here's an example URL with a specific site
example.com/sites/stackoverflow
Your index page is at: localhost:3000/sites
Navigate to localhost:3000/rails/info/routes to see your full app routes in development mode.

Ruby on Rails 3: Change default controller and parameter order in routing

I have a Rails app that has a controller called domain which has a nested controller called subdomain and stats. I have defined them in routes.rb:
resources :domains do
resources :subdomains, :stats
end
I have changed the to_param of the domain and subdomain models to use the name of the domain, e.g.: the routing I get is http://site/domains/foo/subdomains/bar.
I would like to tidy it up to so that instead of using http://site/domains/foo/subdomains/bar I could access it with just http://site/foo/subdomains/bar. I have tried the following in routes.rb:
match "/:id/" => "domains#show", :as => :domain
Which works fine, but it only gives me the ability to use the path http://site/foo but for example http://site/foo/subdomains/bar doesn't. I could create match lines for every respective model and nested model but that does nothing to other helpers besides domain_url - i.e. edit_domain_url points to /domains/foo/edit/ instead of /foo/edit.
Is there a way to change the routing so that the resources generates helpers that point to the root url without the 'domains' part?
The single match in your routes creates only one route. Resource helpers create many routes at once. Luckily there are a lot of options for customisation. If you want to omit /domains/ from your paths, it's as simple as:
resources :domains, :path => "/" do
resources :subdomains, :stats
end
With the above in config/routes.rb, running rake routes says the following:
domain_subdomains GET /:domain_id/subdomains(.:format)
domain_subdomains POST /:domain_id/subdomains(.:format)
new_domain_subdomain GET /:domain_id/subdomains/new(.:format)
edit_domain_subdomain GET /:domain_id/subdomains/:id/edit(.:format)
domain_subdomain GET /:domain_id/subdomains/:id(.:format)
domain_subdomain PUT /:domain_id/subdomains/:id(.:format)
domain_subdomain DELETE /:domain_id/subdomains/:id(.:format)
domain_stats GET /:domain_id/stats(.:format)
domain_stats POST /:domain_id/stats(.:format)
new_domain_stat GET /:domain_id/stats/new(.:format)
edit_domain_stat GET /:domain_id/stats/:id/edit(.:format)
domain_stat GET /:domain_id/stats/:id(.:format)
domain_stat PUT /:domain_id/stats/:id(.:format)
domain_stat DELETE /:domain_id/stats/:id(.:format)
domains GET /(.:format)
domains POST /(.:format)
new_domain GET /new(.:format)
edit_domain GET /:id/edit(.:format)
domain GET /:id(.:format)
domain PUT /:id(.:format)
domain DELETE /:id(.:format)
Looks like all the routes you need!

Resources