Rails routes: Nested, Member, Collection, namespace, scope and customizable
Solution 1
**Collection & Member routes**
A member route requires an ID, because it acts on a member.
A collection route doesn't require an ID because it acts on a collection of objects
:member
creates path with pattern /:controller/:id/:your_method
:collection
creates path with the pattern /:controller/:your_method
For example :
map.resources :users, :collection => { :abc => :get } => /users/abc
map.resources :users, :member => { :abc => :get } => /users/1/abc
**Scopes & Namespaces routes**
namespace
andscope
in the Railsroutes
affect the controller names, URIs, and named routes.The scope method gives you fine-grained control:
scope 'url_path_prefix', module: 'module_prefix', as: 'named_route_prefix' do
resources :model_name
end
For Example :
scope 'foo', module: 'bar', as: 'baz' do
resources :posts
end
produces routes as :
Prefix Verb URI Pattern Controller#Action
baz_posts GET /foo/posts(.:format) bar/posts#index
POST /foo/posts(.:format) bar/posts#create
new_baz_post GET /foo/posts/new(.:format) bar/posts#new
edit_baz_post GET /foo/posts/:id/edit(.:format) bar/posts#edit
baz_post GET /foo/posts/:id(.:format) bar/posts#show
PATCH /foo/posts/:id(.:format) bar/posts#update
PUT /foo/posts/:id(.:format) bar/posts#update
DELETE /foo/posts/:id(.:format) bar/posts#destroy
The namespace method is the simple case — it prefixes everything.
namespace :foo do
resources :posts
end
produces routes as :
Prefix Verb URI Pattern Controller#Action
foo_posts GET /foo/posts(.:format) foo/posts#index
POST /foo/posts(.:format) foo/posts#create
new_foo_post GET /foo/posts/new(.:format) foo/posts#new
edit_foo_post GET /foo/posts/:id/edit(.:format) foo/posts#edit
foo_post GET /foo/posts/:id(.:format) foo/posts#show
PATCH /foo/posts/:id(.:format) foo/posts#update
PUT /foo/posts/:id(.:format) foo/posts#update
DELETE /foo/posts/:id(.:format) foo/posts#destroy
**Constraints & Redirect**
Rails routes are executed sequentially, you can mimic conditional login in the following manner:
match '/route' => 'controller#action', :constraints => Model.new
match '/route' => 'user#action'
The first line checks whether the conditions of the constraint are met (i.e., if the request is emanating from a Model domain). If the constraint is satisfied, the request is routed to controller#action.
We can add constraints to routes for multiple uses like for ip-matching, params matching, restrict format parameter, request-based restrictions etc as :
- ip-matching
=> resources :model, constraints: { ip: /172\.124\.\d+\.\d+/ }
- filtering id params
=> match 'model/:id', to: 'model#show' ,constraints: { id: /\d+/}, via: :get
- restrict format params
=> match 'model/:id', to: 'model#show' ,constraints: { format: 'json' }, via: :get
- request-based constraints
=> get 'admin/', to: 'admin#show', constraints: { subdomain: 'admin' }
Solution 2
Use a singular resource for it:
resource :profile
and in controller manipulate the profile of current user.
As for complex routes - usually namespaces, nested resources with shallow routes and custom actions are all that is needed.
Solution 3
You can go through this answer which answers you first part of the question.
To answer second part of your question. You can treat "profile" as your singular resource (the singularity of the noun itself represents a singular resource). For a detailed description you can refer to this link.
Comments
-
7urkm3n over 1 year
I am trying to understand more about Rails routes.
Member and Collection
# Example resource route with options: resources :products do member do get 'short' post 'toggle' end collection do get 'sold' end end
Namespace and Scope
# Example resource route within a namespace: namespace :admin do resources :products end scope :admin do resources :products end
Constraints, Redirect_to
# Example resource route with options: get "/questions", to: redirect {|params, req| begin id = req.params[:category_id] cat = Category.find(id) "/abc/#{cat.slug}" rescue "/questions" end }
Customization:
resources :profiles
original url from
resource profiles
for edit.http://localhost:3000/profiles/1/edit
I want to make it for users available only through click
edit profile
and see url like in below.http://localhost:3000/profile/edit
Also, is there advanced routing, How most big companies design their routes in rails ? I would be really glad to see new kind of routes if there exist.
Thank You !
-
7urkm3n over 7 yearsTHX, another question, i have
resource :questions
but also i do haveconstraints: { subdomain: 'blog' }
andresource :posts
under it. Now when I am going to subdomain blog, i am still can see questions. do u block to not give access for question