Rails3 routing precedence - ruby-on-rails-3

I'm creating a simple CMS with Rails 3. In my routes.rb file I have the following entry to catch all routes:
match '*url', :controller => 'site', :action => 'dynamic_page'
I'm using ckeditor gem for editor support. My rake routes is as follows:
root /(.:format) {:action=>"index", :controller=>"site"}
/*url(.:format) {:action=>"dynamic_page", :controller=>"site"}
ckeditor_pictures GET /ckeditor/pictures(.:format) {:action=>"index", :controller=>"ckeditor/pictures"}
ckeditor_pictures POST /ckeditor/pictures(.:format) {:action=>"create", :controller=>"ckeditor/pictures"}
ckeditor_picture DELETE /ckeditor/pictures/:id(.:format) {:action=>"destroy", :controller=>"ckeditor/pictures"}
ckeditor_attachment_files GET /ckeditor/attachment_files(.:format) {:action=>"index", :controller=>"ckeditor/attachment_files"}
ckeditor_attachment_files POST /ckeditor/attachment_files(.:format) {:action=>"create", :controller=>"ckeditor/attachment_files"}
ckeditor_attachment_file DELETE /ckeditor/attachment_files/:id(.:format) {:action=>"destroy", :controller=>"ckeditor/attachment_files"}
My problem is, as you can see:
/*url(.:format) {:action=>"dynamic_page", :controller=>"site"}
..loads before the ckeditor routes and hence ckeditor routes are not working. Can someone help me out on loading ckeditor routes before:
/*url(.:format) {:action=>"dynamic_page", :controller=>"site"}
Thanks in advance.

The routes files is processed in order from top to bottom, so just change the order of the routes so that your catch-all is after the ckeditor stuff.

The solution I came up with is adding the ckeditor routes to the routes.rb file manually
like this
namespace :ckeditor, :only => [:index, :create, :destroy] do
resources :pictures
resources :attachment_files
end
match '*url', :controller => 'site', :action => 'dynamic_page'
Now its working fine

Related

Custom Rails 3 routes

Suppose I have an events controller. If I request /events by GET it will respond with index action in news controller, this view will display future events.
I want to add a new action called past, it is like index, which return an array of Events but with another query.
I have added to routes.rb this chunk:
resources :events do
collection do
get :past
end
end
and I this chuck to events_controller:
def history
#events => Event.past
render :template => 'index'
end
But when I request http://127.0.0.1:3000/events/past in browser it does not work, in log are thrown these lines:
Started GET "/events/past" for 127.0.0.1 at 2012-04-02 19:32:01 -0500
Processing by EventsController#show as HTML
Parameters: {"id"=>"past"}
And finally here you have rake routes output:
events GET /events(.:format) {:action=>"index", :controller=>"events"}
event GET /events/:id(.:format) {:action=>"show", :controller=>"events"}
past_events GET /events/past(.:format) {:action=>"past", :controller=>"events"}
contact_us_event POST /events/:id/contact_us(.:format) {:action=>"contact_us", :controller=>"events"}
GET /events(.:format) {:action=>"index", :controller=>"events"}
POST /events(.:format) {:action=>"create", :controller=>"events"}
new_event GET /events/new(.:format) {:action=>"new", :controller=>"events"}
edit_event GET /events/:id/edit(.:format) {:action=>"edit", :controller=>"events"}
GET /events/:id(.:format) {:action=>"show", :controller=>"events"}
PUT /events/:id(.:format) {:action=>"update", :controller=>"events"}
DELETE /events/:id(.:format) {:action=>"destroy", :controller=>"events"}
Other test was check routes using Rails console:
$ script/rails c
1.9.2-p318 :001 > rs = ActionController::Routing::Routes
1.9.2-p318 :002 > rs.recognize_path "/events/past", :method => :get
=> {:action=>"show", :controller=>"events", :id=>"past"}
What's wrong?
The problem was on routes precedence, here you have a routes.rb chunk that works:
resources :events, :only => [:index, :show] do
get 'past', :on => :collection
post 'contact_us', :on => :member
end
Try:
resources :events do
get :past, :to => "events#past"
end
I don't think you need the collection context. (And you might not need the :to part)
Update
Another way to do it is to put the event call above the resource. Assuming you don't need the collection with it.
get 'events/past', :to => "events#past"
resources :events
Should provide you with the correct routes.
For reference: Rails 3 routes: How to avoid conflict with 'show' action?

Rails 3 nested resources short name?

I'm in the process of upgrading a Rails 2.3 app to Rails 3. In the Rails 2.3 router, it was possible to set a :name_prefix of nil on nested resources to get a shorter name. The actual URL would still be fully qualified, but the code could use a shorter name. E.g.,:
map.resources :sites do |site|
site.resources :groups, :as => :groups, :controller => :url_groups, :name_prefix => nil, :member => { :clone => :post } do |group|
group.resources :tests, :as => :tests, :controller => :test_runs, :name_prefix => nil, :collection => { :latest => :get }
end
end
would allow one to use latest_tests_path. I can't figure out how to do the same thing with Rails 3, so I'm stuck with latest_site_group_tests_path. If that's the way it needs to be, I can just go through the code and change every instance of it. But I wanted to make sure I didn't miss anything first. And for better or worse, I do need to maintain the URL structure, so shallow routes don't seem to be the answer.
Good news is that Rails 3 still has the ability to setup arbitrary/abbreviated url helpers. Rather than a parameter to the resources method, you can create short-hand url helpers with the match declaration in routes.rb.
Say we have routes setup like this (noting that you need to maintain the 3 levels of nesting):
resources :sites do
resources :groups, :controller => :url_groups do
member do
post :clone
end
resources :test_runs do
collection do
get :latest
end
end
end
end
We get all the standard url helpers (rake routes):
clone_site_group POST /sites/:site_id/groups/:id/clone(.:format) {:action=>"clone", :controller=>"url_groups"}
latest_site_group_test_runs GET /sites/:site_id/groups/:group_id/test_runs/latest(.:format) {:action=>"latest", :controller=>"test_runs"}
site_group_test_runs GET /sites/:site_id/groups/:group_id/test_runs(.:format) {:action=>"index", :controller=>"test_runs"}
(etc)
But to create something shorter than latest_site_group_test_runs_path(site,group), add a match declaration to routes.rb like this:
match 'sites/:site_id/groups/:id/test_runs/latest' => 'test_runs#latest', :as => :latest_tests
Now you can use latest_tests_path(site,group) or latest_tests_url(site,group) to generate the fully nested path.
If your aim is brevity, you could also use implicit polymorphic paths (as long as you have all your models aligned with resource paths).
For example, given #site #1 and #group #1, all of the following will now generate the same path '/sites/1/groups/1/test_runs/latest':
= link_to "latest tests", latest_site_group_test_runs_path(#site,#group) # std helper
= link_to "latest tests", latest_tests_path(#site,#group) # match helper
= link_to "latest tests", [:latest,#site,#group,:test_runs] # implicit polymorphic path
Hope that helps! Seems like you should be able to get the flexibility you need for the app migration.
NB: I glossed over the lurking issue of having a model called "Test" since that's off topic;-) There are a few model names that are a neverending source of pain because of namespace and keyword conflicts. My other favourite is when I really wanted to have a mode called "Case" (since that matched the problem domain best. Bad idea, rapidly reversed!)
There's the :shallow option (see the documentation), but I'm not sure it fits your use case:
resources :sites, :shallow => true
resources :groups do
resources :tests
end
end
It has the disadvantage of creating a bunch of additional routes:
group_tests GET /groups/:group_id/tests(.:format) {:action=>"index", :controller=>"tests"}
POST /groups/:group_id/tests(.:format) {:action=>"create", :controller=>"tests"}
new_group_test GET /groups/:group_id/tests/creer(.:format) {:action=>"new", :controller=>"tests"}
edit_test GET /tests/:id/modifier(.:format) {:action=>"edit", :controller=>"tests"}
test GET /tests/:id(.:format) {:action=>"show", :controller=>"tests"}
PUT /tests/:id(.:format) {:action=>"update", :controller=>"tests"}
DELETE /tests/:id(.:format) {:action=>"destroy", :controller=>"tests"}
site_groups GET /sites/:site_id/groups(.:format) {:action=>"index", :controller=>"groups"}
POST /sites/:site_id/groups(.:format) {:action=>"create", :controller=>"groups"}
new_site_group GET /sites/:site_id/groups/creer(.:format) {:action=>"new", :controller=>"groups"}
edit_group GET /groups/:id/modifier(.:format) {:action=>"edit", :controller=>"groups"}
group GET /groups/:id(.:format) {:action=>"show", :controller=>"groups"}
PUT /groups/:id(.:format) {:action=>"update", :controller=>"groups"}
DELETE /groups/:id(.:format) {:action=>"destroy", :controller=>"groups"}
sites GET /sites(.:format) {:action=>"index", :controller=>"sites"}
POST /sites(.:format) {:action=>"create", :controller=>"sites"}
new_site GET /sites/creer(.:format) {:action=>"new", :controller=>"sites"}
edit_site GET /sites/:id/modifier(.: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"}
Besides, the shallow nesting only applies to the following routes: :show, :edit, :update, :destroy.
I wanted something like this too, clearly it feels redundant to type the prefixes in named routes all the time for resources that only exist as nested. I was able to get what I wanted using scope, I think this is what you sought too:
resources :sites
scope :path => '/sites/:site_id' do
resources :groups, :controller => :url_groups do
post :clone, :on => :member
end
end
scope :path => '/sites/:site_id/groups/:group_id' do
resources :tests, :controller => :test_runs do
get :latest, :on => :collection
end
end
The rake routes output:
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
PUT /sites/:id(.:format) sites#update
DELETE /sites/:id(.:format) sites#destroy
clone_group POST /sites/:site_id/groups/:id/clone(.:format) url_groups#clone
groups GET /sites/:site_id/groups(.:format) url_groups#index
POST /sites/:site_id/groups(.:format) url_groups#create
new_group GET /sites/:site_id/groups/new(.:format) url_groups#new
edit_group GET /sites/:site_id/groups/:id/edit(.:format) url_groups#edit
group GET /sites/:site_id/groups/:id(.:format) url_groups#show
PUT /sites/:site_id/groups/:id(.:format) url_groups#update
DELETE /sites/:site_id/groups/:id(.:format) url_groups#destroy
latest_tests GET /sites/:site_id/groups/:group_id/tests/latest(.:format) test_runs#latest
tests GET /sites/:site_id/groups/:group_id/tests(.:format) test_runs#index
POST /sites/:site_id/groups/:group_id/tests(.:format) test_runs#create
new_test GET /sites/:site_id/groups/:group_id/tests/new(.:format) test_runs#new
edit_test GET /sites/:site_id/groups/:group_id/tests/:id/edit(.:format) test_runs#edit
test GET /sites/:site_id/groups/:group_id/tests/:id(.:format) test_runs#show
PUT /sites/:site_id/groups/:group_id/tests/:id(.:format) test_runs#update
DELETE /sites/:site_id/groups/:group_id/tests/:id(.:format) test_runs#destroy
Update: Duh, I left the static segments of the scope paths out of my example. Fixed.

How do I remove the Devise route to sign up?

I'm using Devise in a Rails 3 app, but in this case, a user must be created by an existing user, who determines what permissions he/she will have.
Because of this, I want:
To remove the route for users to sign up.
To still allow users to edit their profiles (change email address and password) after they have signed up
How can I do this?
Currently, I'm effectively removing this route by placing the following before devise_for :users:
match 'users/sign_up' => redirect('/404.html')
That works, but I imagine there's a better way, right?
Update
As Benoit Garret said, the best solution in my case is to skip creating the registrations routes en masse and just create the ones I actually want.
To do that, I first ran rake routes, then used the output to re-create the ones I wanted. The end result was this:
devise_for :users, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
Note that:
I still have :registerable in my User model
devise/registrations handles updating email and password
Updating other user attributes - permissions, etc - is handled by a different controller
Actual answer:
Remove the route for the default Devise paths; i.e.:
devise_for :users, path_names: {
sign_up: ''
}
you can do this in your model
# typical devise setup in User.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
change it to:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
notice that the symbol :registerable was removed
That's it, nothing else is required. All routes and links to registration page are magically removed too.
I tried to do this as well, but a thread on the devise google group dissuaded me from searching for a really clean solution.
I'll quote José Valim (the Devise maintainer) :
There isn't a straight-forward option. You can either provide a patch
or use :skip => :registerable and add only the routes you want.
The original question was :
Is there any good way to remove a specific route (the delete route)
from Rails?
I had similar issue tried to remove devise_invitable paths for create and new :
before:
devise_for :users
rake routes
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
user_invitation POST /users/invitation(.:format) devise/invitations#create
new_user_invitation GET /users/invitation/new(.:format) devise/invitations#new
PUT /users/invitation(.:format) devise/invitations#update
after
devise_for :users , :skip => 'invitation'
devise_scope :user do
get "/users/invitation/accept", :to => "devise/invitations#edit", :as => 'accept_user_invitation'
put "/users/invitation", :to => "devise/invitations#update", :as => nil
end
rake routes
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
PUT /users/invitation(.:format) devise/invitations#update
note 1 devise scope https://github.com/plataformatec/devise#configuring-routes
note 2 I'm applying it on devise_invitable but it will work with any devise *able feature
Important note: see that devise_scope is on user not users ? that's correct, watch out for this ! It can cause lot of pain giving you this problem:
Started GET "/users/invitation/accept?invitation_token=xxxxxxx" for 127.0.0.1
Processing by Devise::InvitationsController#edit as HTML
Parameters: {"invitation_token"=>"6Fy5CgFHtjWfjsCyr3hG"}
[Devise] Could not find devise mapping for path "/users/invitation/accept? invitation_token=6Fy5CgFHtjWfjsCyr3hG".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
match "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
#request.env["devise.mapping"] = Devise.mappings[:user]
I found another post similar to this one and wanted to share an answer #chrisnicola gave. In the post they were attempting to only block user signup's during production.
You could also modify the registrations controller. You can use something like this:
In "app/controllers/registrations_controller.rb"
class RegistrationsController < Devise::RegistrationsController
def new
flash[:info] = 'Registrations are not open.'
redirect_to root_path
end
def create
flash[:info] = 'Registrations are not open.'
redirect_to root_path
end
end
This will override devise's controller and use the above methods instead. They added flash messages incase that someone somehow made it to the sign_up page. You should also be able to change the redirect to any path you like.
Also in "config/routes.rb" you can add this:
devise_for :users, :controllers => { :registrations => "registrations" }
Leaving it like this will allow you to use the standard devise edit your profile. If you wish you can still override the edit profile option by including
def update
end
in the "app/controllers/registrations_controller.rb"
This is an old question - but I recently had solve the same issue and came up with a solution which is far more elegant than:
devise_for :users, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
And it gives the default names for the named routes (like cancel_user_registration) without being excessively verbose.
devise_for :users, skip: [:registrations]
# Recreates the Devise registrations routes
# They act on a singular user (the signed in user)
# Add the actions you want in 'only:'
resource :users,
only: [:edit, :update, :destroy],
controller: 'devise/registrations',
as: :user_registration do
get 'cancel'
end
rake routes output with the default devise modules:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
You can override the "devise_scope" by placing it before the "devise_for".
devise_scope :user do
get "/users/sign_up", :to => "sites#index"
end
devise_for :users
Not sure if this is the best way but its my solution currently, as it just redirects back to the sign in page.
I liked #max's answer, but when trying to use it I ran into an error due to devise_mapping being nil.
I modified his solution slightly to one that seems to address the issue. It required wrapping the call to resource inside devise_scope.
devise_for :users, skip: [:registrations]
devise_scope :user do
resource :users,
only: [:edit, :update, :destroy],
controller: 'devise/registrations',
as: :user_registration do
get 'cancel'
end
end
Note that devise_scope expects the singular :user whereas resource expects the plural :users.
Do This in routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
devise_scope :user do
get "/sign_in", :to => "devise/sessions#new"
get "/sign_up", :to => "devise/registrations#new"
end
you will get an error now while you come to sign in page, to fix it.
Do this change in: app/views/devise/shared/_links.erb
<% if request.path != "/sign_in" %>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<% end %>
I've found this to work well without messing with routes or adding application controller methods. My approach is to override the devise method. Add this to app/controllers/devise/registrations_controller.rb
I've omitted the other methods for brevity.
class Devise::RegistrationsController < DeviseController
...
# GET /resource/sign_up
def new
redirect_to root_path
end
....
end
Also to remove illusion that this path is still reachable from other views you might also want to remove this code from app/views/devise/shared/_links.erb
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
For others in my case.
With devise (3.5.2).
I successfully removed the routes to signup, but kept the ones to edit the profile, with the following code.
#routes.rb
devise_for :users, skip: [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put '/users(.:format)' => 'devise/registrations#update', as: 'user_registration'
patch '/users(.:format)' => 'devise/registrations#update'
end
Here's the slightly different route I went. It makes it so you don't have to override the devise/shared/_links.html.erb view.
In app/models/user.rb:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
In config/routes.rb:
devise_for :users
devise_scope :user do
put 'users' => 'devise/registrations#update', as: 'user_registration'
get 'users/edit' => 'devise/registrations#edit', as: 'edit_user_registration'
delete 'users' => 'devise/registrations#destroy', as: 'registration'
end
Before:
$ rake routes | grep devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
After:
$ rake routes | grep devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
user_registration PUT /users(.:format) devise/registrations#update
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
registration DELETE /users(.:format) devise/registrations#destroy
Instead of searching for a hard solution. I used the below approaches.
Delete the sign_up form from page (path devise/registrations/new.html.erb) and replace it with custom info.
Redirect the incoming traffic to some other page. Like below in routes.rb
get "/users/sign_up", to: redirect('/')
post "/users/sign_up", to: redirect('/')
Make sure to write it before devise_for :users
I had the same issue and I found it a bit bad practise to redirect users from the registration page. So my solution is basically is not using :registrable at all.
What I did was to create a similar page like edit user details which looked like:
<%= form_tag(update_user_update_path, method: :post) do %>  
<br>
<%= label_tag(:currPassword, 'Current password:') %> <%= password_field_tag(:currPassword) %> <br>
<%= label_tag(:newPassword, 'New password:') %> <%= password_field_tag(:newPassword) %> <br>
<%= label_tag(:newPasswordConfirm, 'Confirm new password:') %> <%= password_field_tag(:newPasswordConfirm) %> <br>
<%= submit_tag('Update') %>
<% end %>
So this form submits into a new post end point that updates the password, which looks like:
def update
currPass = params['currPassword']
newPass1 = params['newPassword']
newPass2 = params['newPasswordConfirm']
currentUserParams = Hash.new()
currentUserParams[:current_password] = currPass
currentUserParams[:password] = newPass1
currentUserParams[:password_confirmation] = newPass2
#result = current_user.update_with_password(currentUserParams)
end
Later on you can use the #result in your view to tell the user whether the password is updated or not.
By changing the routes there are a whole bunch of other problems that come with that. The easiest method I have found is to do the following.
ApplicationController < ActionController::Base
before_action :dont_allow_user_self_registration
private
def dont_allow_user_self_registration
if ['devise/registrations','devise_invitable/registrations'].include?(params[:controller]) && ['new','create'].include?(params[:action])
redirect_to root_path
end
end
end
You could modify the devise gem itself. First, run this command to find the installed location of using:
gem which devise
Let's suppose the path is:
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise
Then go to
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise/lib/devise/rails and edit routes.rb in that directory. There is a method called def devise_registration(mapping, controllers) which you can modify to get rid of the new action. You can also completely remove the mappings for devise_registration

update instead of show being called in REST rails form submission

I have a form that a user submits. The form is for a user. I have the following in my routes.rb file:
resources :users, :except => [:new]
root :to => 'pages#home'
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
In the users_controller.rb:
def create
#title = "Home"
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to user_path(#user), :flash => {:success => "Your friend's details have been saved.The surprise has begin"} }
format.js
else
format.html { render :template => 'pages/home'}
format.js
end
end
end
This form is being submitted with a regular POST request and not Ajax.
I want to know why the Update template is being requested after the form is successfully submitted instead of the Show.
The output from rake routes is as follows:
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"}
root /(.:format) {:controller=>"pages", :action=>"home"}
contact /contact(.:format) {:controller=>"pages", :action=>"contact"}
about /about(.:format) {:controller=>"pages", :action=>"about"}
help /help(.:format) {:controller=>"pages", :action=>"help"}
Thanks in advance.
What is the code for the controller and view of this form? Is there an existing user object when you generate the form or do you create a new user object (ie. #user = User.new in your controller)? If there is an existing user then the form will submit to update.
Your route and controller code look good, i.e. it should be sending you to the show method in your users_controller. I'd put some debbugging code in there, i.e. logger.debug("Inside Show") to see if the show method was being called.
You could also include the output of rake routes in your edited question, it might be informative to show where the user_path helper is going to send the redirect.
ian.

Problem overriding Devise::RegistrationsController

I've read similar articles like Override devise registrations controller , but Devise in my app doesn't override correctly.
I am using Devise 1.4.2 and Rails 3.0.9 on my Mac (OSX 10.6.8).
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
debugger
end
def create
debugger
end
end
# config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
Then I started my local server with --debugger option (ruby-debug19 is installed) and when access to /users/sign_up, debugger doesn't trigger.
rails server --debugger
Started GET "/users/sign_up" for 127.0.0.1 at 2011-07-11 21:21:46 +0900
Processing by Devise::RegistrationsController#new as HTML
Rendered devise/shared/_links.erb (3.8ms)
Rendered devise/registrations/new.html.erb within layouts/application (20.4ms)
Updated: I checked my routings with "rake routes", but the routing for sign_up still remains as below.
user_registration POST /users(.:format) {
:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /users/sign_up(.:format) {
:action=>"new", :controller=>"devise/registrations"}
I want :controller to point "registrations" (without "devise/") when POST.
What am I missing?
In your routes.rb file,
You can amend your devise routes in the following way:
devise_for :users, :controllers => { :registrations => 'registrations' }