In my routes file, I have a resource called products. The index action of the products resource is also my root path.
resources :products
root :to => "products#index"
When I use the helper method products_path (in a redirect or link), it returns "/products". But what I want is for it to return "/". I know it's the same page, but I want to keep my URL's consistent.
How can I fix this?
Thanks!
root :to => 'products#index', :as => :products
match '', :to => 'products#index', :as => :root # recreate named root_path, if you use it anywhere
This will need to appear below your resources :products as it does in your example above. This will override the products_path and products_url you'd get from resources. Run rake routes before and after to compare.
if you only want to change Index try excluding it first then defining it on its own like so:
resources :products, :except => [:index]
resources :products, :only => [:index], :path => '/'
root_path() should return /
I guess you could redefine the products_path to be the same as root_path (like in a helper file):
def products_path(*params)
root_path *params
end
Related
I want to replace the normal /users/:id route that is created by the resources command, with a more abstract /profile route. It won't be possible to view other users profiles in my app, and therefor the current route is unnecessary specific.
I have tried to overwrite the route created by 'resources :users' with:
get '/profile', to: 'users#show'
and other variances and combinations, but can't seem to get it right. Either the controller can't find the user because of a missing id or it simply can't find the route.
Thanks for the help!
You can use this code in routes.rb file:
resources :users, :except => :show
collection do
get 'profile', :action => 'show'
end
end
It will generate url "/users/profile".
But, if u want to use only '/profile', then don't create route as collection inside users resources block.
resources :users, :except => :show
get 'profile' => "users#show", :as => :user_profile
It will redirect '/profile' to show action in users controller.
I suggest simply adding a users/me route pointing to the show action of your UsersController like so:
resources :users, only: [] do
collection do
get 'me', action: :show
end
end
You can also use the match keyword in routes.rb file.
match 'users/:id' => 'users#show', as: :user_profile, via: :get
I am new to ruby on rails.
Here is my routes.rb
RpxNowExample::Application.routes.draw do
root :to => "users#index"
resources :users
end
Normally my functionality is working fine, but I want to make a tweak. I want it to redirect to another view "promptemail" using the same controller calling another action if a condition is true i.e
if(#provider == "Twitter")
redirect_to :action => :promptemail
end
It should take me to that promptemail view.
You can pass a block to your resources definition to add extra actions outside of the standard:
resources :users do
match :promptemail, :via => [:get], :on => :member
end
The :via option allows you to restrict on get, post, put etc, the :on parameter will take either :member, or :collection.
:collection will operate on a collection, so similar to the index action, :member will operate on an individual record. As such if you specify your route as :on => :member, you will need to provide an object or id when you generate the route.
More info about adding routes to resources can be found here: http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
Using the same controller calling another action-
Try:
routes.rb:
RpxNowExample::Application.routes.draw do
root :to => "users#index"
resources :users do
collection do
get 'promptemail'
end
Your controller:
if(#provider == "Twitter")
redirect_to :promptemail
end
Note: - No need to call action in redirect_to as you are calling the action within the same controller.
In my AdminController, I have methods named as edit, update and update_admin. And in route.rb
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
When I navigate the url '/users/edit/1' matches. From this page i want to call the action method in update_admin in AdminController. How to do this?
My edit.erb has
<%= render :partial => '/submit', :locals =
> {:button_html => f.submit('Update'), :validate_present => true}
%>
at first, to check your routes go to console and do
rake routes | grep session
there you will get list all routes of your rails application (matched to the grep)
at second i dont get your routes.rb
would you do
resources :session, :only => [update] do
match '/:controller(/:action(/:id))'
end
or
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
these are 2 different things. i think you want the last one. but here we go, there is another problem
resources :session, :only=>[update]
this throws an error.(undefined local variable or method `update' for #)
if you want to specify actions, you need to do it as a key
resources :session, :only=>[:update]
but you also want the edit message, (edit is the form, update the action to save the changes) so you have to do
resources :users, :only=>[:edit, :update]
now check your rake routes and see voila!
edit_session GET /session/:id/edit(.:format) {:action=>"edit", :controller=>"session"}
session PUT /session/:id(.:format) {:action=>"update", :controller=>"session"}
//edit
if you want to do this in your admin_controller you should have a namespace
#i take example for a user
namespace :admin do
resources :user :only => [:edit, :update]
end
if you want now to link to it from a view the route is named
edit_admin_user_path
and in a form you need to bring the namespace also in the form_for like:
=form_for [:admin, #user] do |f|
It used to be that you could load Typus routes exactly where you needed them by placing
Typus::Routes.draw(map)
at the appropriate point in your routes.rb file. It seems that this is no longer supported and that they're always loaded after all of the application routes. This causes problems with catchall routes which must be defined last. Does anyone know how to control the load order for typus now? Is there a way to get them defined before any of the app routes rather than after? Thanks!
I got around it by leaving my catch-all routes at the end of my apps routes.rb BUT excluding it from matching for Typus urls:
# A catch all route
match '*path' => 'content#show', :constraints => lambda{|request|
!request.path.starts_with?("/admin") # excluded if typus will be taking it...
}
This may or may now work for you...
I'm looking for the same answer.
At the moment I have resorted to copying the contents from typus's config/routes.rb and placing it into my routes.rb file, before the catchall route.
It's a horrible, hackish solution, but it's solving my immediate problem.
Example:
# TODO: KLUDGE: MANUALLY BRING THE TYPUS ROUTES IN
# Typus used to provide :
# Typus::Routes.draw(map)
# But that is no longer the case.
scope "admin", :module => :admin, :as => "admin" do
match "/" => "dashboard#show", :as => "dashboard"
match "user_guide" => "base#user_guide"
if Typus.authentication == :session
resource :session, :only => [:new, :create, :destroy], :controller => :session
resources :account, :only => [:new, :create, :show, :forgot_password] do
collection do
get :forgot_password
post :send_password
end
end
end
Typus.models.map { |i| i.to_resource }.each do |resource|
match "#{resource}(/:action(/:id(.:format)))", :controller => resource
end
Typus.resources.map { |i| i.underscore }.each do |resource|
match "#{resource}(/:action(/:id(.:format)))", :controller => resource
end
end
# END KLUDGE
# Catch all to the state page handler
match '/:page' => 'pages#show', :as => 'page'
I'm getting the following error:
Unknown action
No action responded to show. Actions: activate, destroy, index, org_deals, search, and suspend
Controller:
class Admin::HomepagesController < Admin::ApplicationController
def org_deals
#organization = Organization.find(:all)
end
Routes:
map.root :controller => 'main'
map.admin '/admin', :controller => 'admin/main'
map.namespace :admin do |admin|
admin.resources :organizations, :collection => {:search => :get}, :member => {:suspend => :get, :activate => :get}
To note: This is a controller inside of a controller.
Any idea why this is defaulting to show?
Update:
I updated what the routes syntax is. Read that article, and tried quite a few variations but its still adamantly looking for a show.
Firstly, it looks like your routes file has the wrong syntax. If you are trying to establish routes for nested resources, you'd do it like so:
map.resources :admin
admin.resources :organizations
end
This would give you paths such as:
/admin/
/admin/1
/admin/1/organizations
/admin/1/organizations/1
The mapping from route to controller/action is done via a Rails convention, where HTTP verbs are assigned in ways that are useful for the typical CRUD operations. For example:
/admin/1/organizations/1
would map to several actions in the OrganizationsController, distinguished by the type of verb:
/admin/1/organizations/1 # GET -> :action => :show
/admin/1/organizations/1 # PUT -> :action => :update
/admin/1/organizations/1 # DELETE -> :action => :destroy
"Show" is one of the seven standard resourceful actions that Rails gives you by default. You can exclude "show" with the directive :except => :show, or specify only the resourceful actions you want with :only => :update, for example.
I recommend you look at Rails Routing from the Outside In, which is a great introduction to this topic.
EDIT
I see I ignored the namespacing in my answer, sorry. How about this:
map.namespace(:admin) do |admin|
admin.resources :homepages, :member => { :org_deals => :get }
end
This will generate your org_deals action as a GET with an id parameter (for the organization). You also get a show route, along with the six other resourceful routes. rake routes shows this:
org_deals_admin_homepage GET /admin/homepages/:id/org_deals(.:format) {:controller=>"admin/homepages", :action=>"org_deals"}
Of course your homepages_controller.rb has to live in app/controllers/admin/
EDIT redux
Actually, you want organizations in the path, I'll bet, in which case:
map.namespace(:admin) do |admin|
admin.resources :organizations, :controller => :homepages, :member => { :org_deals => :get }
end
which gives you:
org_deals_admin_organization GET /admin/organizations/:id/org_deals(.:format) {:controller=>"admin/homepages", :action=>"org_deals"}
By specifying admin.resources ... you are telling Rails you want the seven default different routes in your application. If you do not want them, and only want the ones you specify, do not use .resources. Show is called because that's the default route called for a GET request with a path such as /admin/id when you have the default resources.