How to group/nest routes in rails like you can in laravel? - ruby-on-rails

I'm switching from using a laravel php framework to a rails framework and cannot figure out how to get nested routes working in rails like it did in laravel. In laravel it would work like this:
Route::group(['prefix' => 'healthandwelness'], function() {
Route::get('', [
'uses' => 'healthandwelness#index'
]);
Route::group(['prefix' => 'healthcare'], function() {
Route::get('', [
'uses' => 'healthcare#index'
]);
Route::get('{article_id}', [
'uses' => 'article#index'
]);
]);
});
Which would give me the routes:
/healthandwellness
/healthandwellness/healthcare
/healthandwellness/healthcare/{article_id}
The only way I've seen to nest routes in rails is with resources which I've used to tried and recreate my routes in rails like this:
resources :healthandwellness do
resources :healthcare
end
But the nature of resources makes this route into the following gets:
/healthandwellness
/healthandwellness/:health_and_wellness_id/healthcare
/healthandwellness/:health_and_wellness_id/healthcare/:id
Is there anyway to do what I am looking for in rails and recreate what I was able to do laravel?

You can use namespace:
namespace :healthandwellness do
resources :healthcare
end
Note that this assumes that your controller is located in app/controllers/healthsandwellness/healthcare_controller.rb and should be defined as follows:
class Healthandwellness::HealthcareController < ApplicationController
...
end
If you want to keep your controller under apps/controller and not scoped under app/controllers/healthandwellness, you can use scope:
scope '/healthandwellness' do
resources :healthcare
end
The documentation here provides good examples of namespace and scope

Related

Change model name in browser rails

I have a model in rails and I called it free_mess
And my routes file contain resources :free_mess
Obviously this model name is not ideal to show in the browser, it shows up like this:
localhost:3000/free_mess/show
localhost:3000/free_mess/index
localhost:3000/free_mess/message1
I need to change the free_mess in the browser to something more readable like 'messages'. So that the browser shows this:
localhost:3000/messages/show
localhost:3000/messages/index
localhost:3000/messages/message1
resources :free_mess, path: 'messages'
This will add alias routes in your app.
But if you want to rename the path AND the shhelper methods, then you should do:
resources :stories, :path => :books, :as => :books
See: Overriding the Named Helpers
Do this in config/routes.rb
To get this
localhost:3000/messages/show
localhost:3000/messages/index
localhost:3000/messages/message1
Do this
get 'messages/show' => 'free_mess#show'
get 'messages/index' => 'free_mess#index'
get 'messages/message1' => 'free_mess#message1'
You can specify a path option:
resources :free_mess, path: 'messages'

Creating ruby hash object from Rails routes?

Using rails 4.2.1
I want to store my rails declared routes from config/routes.rb into a ruby hash that I can access or render somewhere.
The hash should be of the format
{
name: 'path',
# e.g.
login: '/login',
home: '/'
}
How do I do this in rails?
Note: I think you get the routes through Rails.application.routes and maybe the names from Rails.application.routes.routes.named_routes.keys, but what's next?
This will give you a Hash where the keys are the route names and the values are the paths:
routes = Hash[Rails.application.routes.routes.map { |r| [r.name, r.path.spec.to_s] }]
routes will now look like:
{
"entities" => "/entities(.:format)",
"new_entity" => "/entities/new(.:format)",
"edit_entity" => "/entities/:id/edit(.:format)",
"entity" => "/entities/:id(.:format)"
}
If you really have to do this, you can:
ri = ActionDispatch::Routing::RoutesInspector.new([])
result = ri.send :collect_routes, Rails.application.routes.routes
The result will be an array of hashes which look like:
{:name=>"product", :verb=>"GET", :path=>"/products/:id(.:format)", :reqs=>"products#show", :regexp=>"^\\/products\\/([^\\/.?]+)(?:\\.([^\\/.?]+))?$"}
You may want to use the JS-Routes gem that generates a javascript file that defines all Rails named routes as javascript helpers.
Setup (just add it to the asset pipeline):
# add to your application.js
/*
= require js-routes
*/
Usage your javascript code like this:
Routes.users_path() // => "/users"
Routes.user_path(1) // => "/users/1"
Routes.user_path(1, {format: 'json'}) // => "/users/1.json"
Find the documentation here: https://github.com/railsware/js-routes#usage

Router for nested resources in a "not usual" Ruby on Rails way

I am using Ruby on Rails 3.0.7 and I am trying to set nested resource routing to make it to work in a "not regular" RoR way.
In my routes.rb file I have
resources :articles do
resources :categories, :only => [:index], :controller => 'articles/categories' # The related controller is Articles::CategoriesController
end
so that I can browse following URLs:
<my_site>/articles/1/categories
<my_site>/articles/2/categories
...
What I would to do is to access new, edit and show controller actions for categories by using the same articles/categories controller used for the nested resource stated above (that is, Articles::CategoriesController) and by accessing these URLs:
<my_site>/articles/categories/new
<my_site>/articles/categories/edit
<my_site>/articles/categories/1
<my_site>/articles/categories/2
...
How can I do that? How I must code the router?
Maybe I can do something by using the router collection method like this
resources :articles do
collection do
# match something here for the Articles::CategoriesController...
end
resources :categories, :only => [:index], :controller => 'articles/categories'
end
but I don't know how to do that.
I'm not real sure what you're trying to do with those routes, so I'm not quite sure how to answer your questions. If your intent is to be able to add a new category for a particular article, or edit all the categories for a particular article, you have to pass an ID for the article. If you're trying to create a new article and a new category all at once, you don't need category in the route, just the article and you can do something like form_for([#article,#category]) in your form and use the build method in your controller. If you can clarify, I might be able to help you further (in other words, it's not hard to construct those routes -- but it depends on what you want to do with them.

How to rewrite URLs using namespaces in Ruby on Rails?

I am running Ruby on Rails 3 and I would like to set up my routes in order to rewrite URLs using namespaces.
In the routes.rb file I have:
namespace "users" do
resources :account_auth
end
So, URLs to "show an"/"create a new" account_auth page are:
http://<site_name>/users/account_auths/1
http://<site_name>/users/account_auths/new
I would like to rewrite/redirect those URLs as/to
# from 'account_auth' to 'auth'
http://<site_name>/users/auth/1
http://<site_name>/users/auth/new
How to do that? If it can be, what kinds of problems could I have?
Use the :path option:
namespace :users do
resources :account_auth, :path => "auth"
end

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