How to write route for the scenario below - ruby

I have a JSON route path that looks like this:
/jobs/{jobid}/employees/{employeeid}/departments/cubes/{cubeid}/register
The following route works fine when there was no cube and cubed:
resources :departments, only: [] do
get 'register', on: :collection
end
I tried doing this:
namespace :departments do
resources :cubes, only: [] do
get 'register', on: :collection
end
end
What change do I need to do in the above code so it will work with the route path?

When I add:
resources :jobs do
resources :employees do
namespace :departments do
get 'cubes/:cube_id/register',
to: 'cubes#register'
end
end
end
to my routes.rb and then run rake routes, I get this line in my output:
GET /jobs/:job_id/employees/:employee_id/departments/cubes/:cube_id/register(.:format) departments/cubes#register

It's not a good practice to nest resources more than 1 level
http://guides.rubyonrails.org/routing.html
Resources should never be nested more than 1 level deep.
http://weblog.jamisbuck.org/2007/2/5/nesting-resources
Rule of thumb: resources should never be nested more than 1 level
deep. A collection may need to be scoped by its parent, but a specific
member can always be accessed directly by an id, and shouldn’t need
scoping (unless the id is not unique, for some reason).

Related

Understanding 'GET' routes in rails

In my routes file I have specified:
resources :cards do
end
Apart from the basic CRUD routes I have another route which is as follows:
get '/cards/get_schema' => 'cards#get_schema'
When I hit this endpoint, I'm actually taken to cards#show. Why does this happen?
One route generated by resources :cards is get '/cards/:id'. Can you see the issue? get_schema is recognized as id. Try this one
resources :cards do
get 'get_schema', on: :collection
end
Or just put that route on top
get '/cards/get_schema' => 'cards#get_schema'
resources :cards
Rails is treating get_schema as the id of a card. The solution is to reorder the route declarations, like so:
get '/cards/get_schema' => 'cards#get_schema'
resources :cards do
end
This way the get_schema route will be matched before the show route.
It depends on the order of routes defined.
Order 1
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resources :cards do
end
get '/cards/get_schema' => 'cards#get_schema'
end
Running routes
rake routes
Output
~/D/p/p/s/console_test> rake routes
Prefix Verb URI Pattern Controller#Action
cards GET /cards(.:format) cards#index
POST /cards(.:format) cards#create
new_card GET /cards/new(.:format) cards#new
edit_card GET /cards/:id/edit(.:format) cards#edit
card GET /cards/:id(.:format) cards#show #<========
PATCH /cards/:id(.:format) cards#update
PUT /cards/:id(.:format) cards#update
DELETE /cards/:id(.:format) cards#destroy
cards_get_schema GET /cards/get_schema(.:format) cards#get_schema #<========
Since show expects cards/:id and is above /cards/get_schema it gets routed to cards#show
Order 2
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
get '/cards/get_schema' => 'cards#get_schema'
resources :cards do
end
end
Running routes
rake routes
Output
~/D/p/p/s/console_test> rake routes
Prefix Verb URI Pattern Controller#Action
cards_get_schema GET /cards/get_schema(.:format) cards#get_schema #<========
cards GET /cards(.:format) cards#index
POST /cards(.:format) cards#create
new_card GET /cards/new(.:format) cards#new
edit_card GET /cards/:id/edit(.:format) cards#edit
card GET /cards/:id(.:format) cards#show #<========
PATCH /cards/:id(.:format) cards#update
PUT /cards/:id(.:format) cards#update
DELETE /cards/:id(.:format) cards#destroy
In this scenario /cards/get_schema will be top level and won't conflict with cards#show

Ruby jsonapi-resources links (relative/absolute)

I am incredibly new to Ruby, so I apologise in advance if this question seems very simple or vague.
Where, when using jsonapi-resources is the base path for JSON API links specified? I wish to change from specifying full URLs to root-relative paths to these resources.
I've found the routes.rb which has
Rails.application.routes.draw do
# Route / to the front-end
root to: 'root#index'
namespace :api do
jsonapi_resources :widgets
// ...more jsonapi_resources calls
end
I am guessing you are looking for something like this?
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
jsonapi_resources :cars, only: [:index]
end
end
end

How to remove the :id Part when doing a Concern

My routes file contains:
concern :generic_table do
get 'search_suggestions' => 'search_suggestions'
end
get 'human_resources/' => 'human_resources#index'
namespace :human_resources do
get 'settings/' => 'settings#index'
namespace :settings do
resources :constants do
concerns :generic_table
end
end
end
And it produces:
/human_resources/settings/constants/:constant_id/search_suggestions(.:format)
human_resources/settings/search_suggestions#search_suggestions
I am trying to remove the /:constant_id/ part and it point to the controller action:
human_resources/settings/constants/search_suggestions#search_suggestions
So in finality it would be
/human_resources/settings/constants/search_suggestions(.:format)
human_resources/settings/constants/search_suggestions#search_suggestions
How can I remove the /:constant_id/ part; and point it directly to my controllers action so my search bar my access the search suggestion for AJAX?
I think you just need to replace the resources block by a namespace one. It is the resources block that generates the parameter.
See also the member block if you need id instead of constant_id.
One extra point: This may not generate the route helpers you want. There are extra options to pass to namespace and related to tailor the helpers.

Adding a view and then properly routing it in rails

Ok everyone,
i am using rails 4.2.0
so i have created three scaffolds but needed to add an additional view to one of my models.
I have a Site and Resident model and what i am looking to accomplish is to create a resident thst ties directly back to the site from a link on the site show page.
In my site controller i have the following.
def new_site_resident
#site.residents.create(resident_params)
end
AND
def resident_params
params.require(:resident).permit(:site_id, :unit_number, :f_name, :m_name, :l_name, :dob)
end
im my routes folder i have
get "/sites/:id/new_site_resident"
and have tried get "/sites/new_site_resident
when i use the get "/sites/new_site_resident it comes back with this error:
Couldn't find Site with 'id'=new_site_resident
^^ i am sure this is telling me it is looking for a site with that as the id.
when i use get "/sites/id/new_site_resident" in routes.rb and then try to go to:
http://localhost:3000/sites/1/new_site_resident it gives the error of:
No route matches [GET] "/sites/1/new_site_resident"
not too sure where to go with this? but as i said before i want to be able to look at the site and then be able to directly create a resident in that link that ties back to the site without having to manually enter the site id as the end uses would know that the site id would be.
Current routes.rb file.
Rails.application.routes.draw do
root 'home#index'
resources :sites
resources :vehicles
resources :residents
get "/sites/:id/new_site_resident"
devise_for :users, controllers: { registrations: "registrations" }
To create route to your action, you can use resources:
resources :sites do
member do
get :new_site_resident
end
end
then you can remove
get "/sites/:id/new_site_resident"
Just move
get "/sites/:id/new_site_resident"
line to the start of the routes file. File should look like
Rails.application.routes.draw do
root 'home#index'
get "/sites/:id/new_site_resident"
resources :sites
resources :vehicles
resources :residents
devise_for :users, controllers: { registrations: "registrations" }
Or try member routes to define this route like
resources :sites do
member do
get :new_site_resident
end
end

Padrino, name route differently from path?

I want to be able to follow a convention closer to what Rails does with resourceful routing. For example, I'm considering "signups" to be a resource, with it's own controller containing "new" and "create" actions.
In app/controllers/signup.rb I have:
MyApp.controllers :signups do
get :index do
# ...
end
post :index do
# ...
end
end
Is there any way I can use these route names, while actually responding on a path other than '/signups'? It feels like Padrino's route naming system is very tightly coupled with the URLs the routes map to.
I've tried:
MyApp.controllers :signups, :map => '/another-path' do
# ...
end
Among various other things without success. Perhaps I should just go back to using Rails... I was just getting frustrated with the startup overhead in TDD and I'm embarking on a new project at the moment (please don't refer me to Spork... that has it's own issues).
This is how I would do what you are asking
# in app/controller/signups.rb
MyApp.controllers :'another-path' do
get '/' do
# ...
end
end

Resources