manage users by an admin in ruby on rails - ruby-on-rails

how can I manage and edit other users profiles as an admin since I have one model and controller (users) ?
I tried to add a new action called updateusers
def updateusers
#other_user=User.find(params[:id])
if #other_user.update_attributes(otherusers_params)
redirect_to '/'
else
redirect_to '/manage'
end
end
the problem here :it is updating my admin user with the other_user's data
stack trace
Started GET "/manage" for ::1 at 2016-03-19 21:06:08 +0300 Processing by UsersController#manage as HTML User Load (1.0ms) SELECT "users".* FROM "users" Rendered users/manage.html.erb within layouts/application (5.0ms) User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Completed 200 OK in 53ms (Views: 51.0ms | ActiveRecord: 1.0ms)
'Started GET "/users/10" for ::1 at 2016-03-19 21:06:10 +0300 Processing by UsersController#show as HTML Parameters: {"id"=>"10"} User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 10]] Rendered users/show.html.erb within layouts/application (0.0ms) User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Completed 200 OK in 37ms (Views: 36.0ms | ActiveRecord: 0.0ms)
Started GET "/editusers/10" for ::1 at 2016-03-19 21:06:11 +0300 Processing by UsersController#editusers as HTML Parameters: {"id"=>"10"} User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 10]] Rendered users/editusers.html.erb within layouts/application (4.0ms) User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Completed 200 OK in 41ms (Views: 39.0ms | ActiveRecord: 1.0ms)
Started PATCH "/users/10" for ::1 at 2016-03-19 21:06:15 +0300 Processing by UsersController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"6M1TGLQUEhiezCCg9/rT5IofdroMiQ0sm+bYcihgGDxTjDdFGU2Riou2p‌​cRk5ncjCtFDGwfBj17Uq7gc0u329w==", "user"=>{"first_name"=>"g", "last_name"=>"g", "email"=>"g#g.g", "role"=>"editor", "image"=>"pic.png", "admins"=>""}, "other"=>"update", "id"=>"10"} User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Unpermitted parameters: role, admins
(0.0ms) begin transaction SQL (1.0ms) UPDATE "users" SET "first_name" = ?, "last_name" = ?, "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["first_name", "g"], ["last_name", "g"], ["email", "g#g.g"], ["updated_at", "2016-03-19 18:06:15.488284"], ["id", 1]] (47.0ms) commit transaction Redirected to localhost:8080/profile Completed 302 Found in 54ms (ActiveRecord: 48.0ms)

If it's updating the wrong user, it means that params[:id] is the id of the user being updated. Are you passing the id of the user you want to update in the params? Try calling puts params.inspect at the top of the controller action to see what data is being passed. You need to look up #other_user with their id and you need to make sure that #other_user's id is being passed with the other form data.

after 10 days ,, Yes i did it - the solution is in the name of submit , I named the two submits with diffrent names <%= f.submit "update", name:"other" %>
then i used the update action like this
def update
if params[:current]
#user = current_user
if #user.update_attributes(user_params)
redirect_to '/profile'
else
redirect_to '/edit'
end
elsif params[:other]
#other_user=User.find(params[:id])
if #other_user.update_attributes(otherusers_params)
redirect_to '/'
else
redirect_to '/manage'
end
end
end

Related

Nested resource failing to update

I'm trying to do what I think should be simple: do a simple edit on a single text string field with the default update action. But it just doesn't seem to work, despite many attempts and alterations.
There are no errors and the flash message responds successfully, but information isn't saved to the database at all:
routes.rb
resources :interviews do
resources :invitations do
put :accept
end
end
views/invitations/edit.html.haml
= simple_form_for [#interview, #invitation] do |f|
= f.error_notification
= f.input :testing
= f.submit 'Edit Invitstion', :class => 'button small'
controllers/invitations_controller.rb
def update
#invitation = Invitation.find(params[:id])
#interview = Interview.find(params[:interview_id])
#invitation.update_attributes(invitation_params)
if #invitation.update_attributes(invitation_params)
redirect_to edit_interview_invitation_path(#interview, #invitation), notice: "Your profile has been successfully updated."
else
render action: "edit"
end
end
private
def invitation_params
params.permit(:user_id, :interview_id, :invitation_id, :session_time, :workflow_state, :testing)
end
And here's the log:
Started PATCH "/interviews/3/invitations/7" for ::1 at 2016-05-15 19:01:52 +0800
Processing by InvitationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"o0U5t0yPN0aE2er+DWK0uxqRGyp4ywfdSrEfvwiSQ3UUaOnr3Fd0raFs1IUqVzizKoqxRU0DDpmvysntB9fdhQ==", "invitation"=>{"interview_id"=>"3", "workflow_state"=>"invited", "session_time"=>"", "testing"=>"testtesttest"}, "commit"=>"Edit Invitstion", "interview_id"=>"3", "id"=>"7"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 7]]
Invitation Load (0.2ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT 1 [["id", 7]]
Role Load (0.2ms) SELECT "roles".* FROM "roles" WHERE "roles"."id" = $1 LIMIT 1 [["id", 3]]
Interview Load (0.2ms) SELECT "interviews".* FROM "interviews" WHERE "interviews"."id" = $1 ORDER BY created_at DESC LIMIT 1 [["id", 3]]
CACHE (0.0ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT 1 [["id", "7"]]
CACHE (0.0ms) SELECT "interviews".* FROM "interviews" WHERE "interviews"."id" = $1 ORDER BY created_at DESC LIMIT 1 [["id", "3"]]
Unpermitted parameters: utf8, _method, authenticity_token, invitation, commit, id
(0.1ms) BEGIN
Invitation Exists (0.4ms) SELECT 1 AS one FROM "invitations" WHERE ("invitations"."user_id" = 3 AND "invitations"."id" != 7 AND "invitations"."interview_id" = 3) LIMIT 1
(0.1ms) COMMIT
Redirected to http://localhost:3000/interviews/3/invitations/7/edit
Completed 302 Found in 12ms (ActiveRecord: 1.6ms)
Started GET "/interviews/3/invitations/7/edit" for ::1 at 2016-05-15 19:01:52 +0800
Processing by InvitationsController#edit as HTML
Parameters: {"interview_id"=>"3", "id"=>"7"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 7]]
Invitation Load (0.3ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."id" = $1 LIMIT 1 [["id", 7]]
Role Load (0.2ms) SELECT "roles".* FROM "roles" WHERE "roles"."id" = $1 LIMIT 1 [["id", 3]]
Interview Load (0.2ms) SELECT "interviews".* FROM "interviews" WHERE "interviews"."id" = $1 ORDER BY created_at DESC LIMIT 1 [["id", 3]]
Rendered invitations/edit.html.haml within layouts/application (6.1ms)
Completed 200 OK in 48ms (Views: 39.1ms | ActiveRecord: 1.6ms)
Check the format of your params object in your logs. Your invitation params are being passed within the params["invitation"] key, yet you're whitelisting and updating your object based on the params in the root params hash.
Also note that your logs are reporting that you're trying to update your invitation with unpermitted params:
Unpermitted parameters: utf8, _method, authenticity_token, invitation, commit, id
You can fix this by simply updating your invitation_params to use params[:invitation] rather than params like so:
def invitation_params
params.require(:invitation).permit(:user_id, :interview_id, :invitation_id, :session_time, :workflow_state, :testing)
end
Also, you might want to consider raising an error if you're trying to update a parameter that's not whitelisted to prevent these sorts of issues in the future.
In your rails config:
config.action_controller.action_on_unpermitted_parameters = :raise

how to manage users by an admin in ruby on rails

how can I manage and edit other users profiles as an admin since I have one model and controller (users) ?
I tried to add a new action called updateusers
def updateusers
#other_user=User.find(params[:id])
if #other_user.update_attributes(otherusers_params)
redirect_to '/'
else
redirect_to '/manage'
end
end
the problem here :it is updating my admin user with the other_user's
data
stack trace
Started GET "/manage" for ::1 at 2016-03-19 21:06:08 +0300 Processing by
UsersController#manage as HTML User Load (1.0ms) SELECT "users".* FROM
"users" Rendered users/manage.html.erb within layouts/application (5.0ms) User
Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1
[["id", 1]] Completed 200 OK in 53ms (Views: 51.0ms | ActiveRecord: 1.0ms)
'Started GET "/users/10" for ::1 at 2016-03-19 21:06:10 +0300 Processing by
UsersController#show as HTML Parameters: {"id"=>"10"} User Load (0.0ms) SELECT
"users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 10]] Rendered
users/show.html.erb within layouts/application (0.0ms) User Load (0.0ms) SELECT
"users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Completed 200
OK in 37ms (Views: 36.0ms | ActiveRecord: 0.0ms)
Started GET "/editusers/10" for ::1 at 2016-03-19 21:06:11 +0300 Processing
by UsersController#editusers as HTML Parameters: {"id"=>"10"} User Load (0.0ms)
SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 10]]
Rendered users/editusers.html.erb within layouts/application (4.0ms) User Load
(1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Completed 200 OK in 41ms (Views: 39.0ms | ActiveRecord: 1.0ms)
Started PATCH "/users/10" for ::1 at 2016-03-19 21:06:15 +0300 Processing by
UsersController#update as HTML Parameters: {"utf8"=>"✓",
"authenticity_token"=>"6M1TGLQUEhiezCCg9/rT5IofdroMiQ0sm+bYcihgGDxTjDdFGU2Riou2p‌​
cRk5ncjCtFDGwfBj17Uq7gc0u329w==", "user"=>{"first_name"=>"g", "last_name"=>"g",
"email"=>"g#g.g", "role"=>"editor", "image"=>"pic.png", "admins"=>""},
"other"=>"update", "id"=>"10"} User Load (0.0ms) SELECT "users".* FROM "users"
WHERE "users"."id" = ? LIMIT 1 [["id", 1]] Unpermitted parameters: role, admins
(0.0ms) begin transaction SQL (1.0ms) UPDATE "users" SET "first_name" = ?,
"last_name" = ?, "email" = ?, "updated_at" = ? WHERE "users"."id" = ?
[["first_name", "g"], ["last_name", "g"], ["email", "g#g.g"], ["updated_at",
"2016-03-19 18:06:15.488284"], ["id", 1]] (47.0ms) commit transaction Redirected
to localhost:8080/profile Completed 302 Found in 54ms (ActiveRecord: 48.0ms)
The user ID of the form in "editusers" is set to your admin (or logged in user). It's hard to say without seeing the code but I think you've set up the editusers form incorrectly. Perhaps using a hidden field to hold the ID of the user you want to update.
Try to avoid that and set up the #user object in the 'editusers' action #user = User.find(10)
Then in your view use a form_for #user do |f| without any hidden fields for the ID.
after 10 days ,, Yes i did it - the solution is in the name of submit , I named the two submits with diffrent names <%= f.submit "update", name:"other" %> then i used the update action like this
def update
if params[:current]
#user = current_user
if #user.update_attributes(user_params)
redirect_to '/profile'
else
redirect_to '/edit'
end
elsif params[:other]
#other_user=User.find(params[:id])
if #other_user.update_attributes(otherusers_params)
redirect_to '/'
else
redirect_to '/manage'
end
end
end

Rails 4 with Clearance password reset issue

I'm building an Rails 4 app with the authentication gem 'clearance'. I'm kind of stuck with the following problem:
When an user forgets his/her password and would like to set a new password, the user is not found. (but exist in DB), this is the server log:
Started PUT "/passwords/1?token=[FILTERED]" for 127.0.0.1 at 2013-08-10 21:00:58 +0200
Processing by PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "password_reset"=>"[FILTERED]", "token"=>"[FILTERED]", "id"=>"1"}
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" IS NULL AND "users"."confirmation_token" = 'bcc6a5b49bc64628eff15bf92761fe1775ef252c' LIMIT 1
Rendered passwords/new.html.slim within layouts/application (0.9ms)
Rendered partials/_favicon_styles.html.slim (0.4ms)
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
Rendered partials/_navigation.html.slim (11.2ms)
Rendered partials/_notification.html.slim (0.1ms)
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
Rendered partials/_footer.html.slim (1.0ms)
Filter chain halted as :forbid_non_existent_user rendered or redirected
Completed 200 OK in 38ms (Views: 33.0ms | ActiveRecord: 2.3ms)
But when a user is logged in, he or she can change password and also login works normally ..
I think the problem is in the query, I am sending the id with the form, but when the id reaches the query it says IS NULL. But I've struggled with it for hours, but can't find the solution.
Also is the 7 times request for cache a problem?
Thanks in advance!
Update
Changed the strong parameters and the 'find_user_by_id_and_confimatrion_token' method as followed:
def find_user_by_id_and_confirmation_token
Clearance.configuration.user_model.
find_by_id_and_confirmation_token params[:**id**], params[:token].to_s
end
This was :user_id, this is not the name of the params.
def password_reset_params
# if params.has_key? :user
# ActiveSupport::Deprecation.warn %{Since locales functionality was added, accessing params[:user] is no longer supported.}
# params[:user][:password]
# else
# params[:password_reset][:password]
# end
params.require(:password_reset).permit(:password_reset, :password, :token, :id)
end
But this throws in another error:
Started PUT "/passwords/1?token=[FILTERED]" for 127.0.0.1 at 2013-08-11 16:31:20 +0200
Processing by PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "password_reset"=>" [FILTERED]", "token"=>"[FILTERED]", "id"=>"1"}
User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'd892a4698f5eff29e34378716ebd46414ad6e8cf' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'd892a4698f5eff29e34378716ebd46414ad6e8cf' LIMIT 1
(0.4ms) BEGIN
User Exists (1.0ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'user#test.nl' AND "users"."id" != 1) LIMIT 1
(0.4ms) ROLLBACK
Rendered passwords/edit.html.slim within layouts/application (1.2ms)
Rendered partials/_favicon_styles.html.slim (0.3ms)
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
Rendered partials/_navigation.html.slim (4.7ms)
Rendered partials/_notification.html.slim (0.1ms)
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
Rendered partials/_footer.html.slim (0.4ms)
Completed 200 OK in 112ms (Views: 12.5ms | ActiveRecord: 4.1ms)
It says that the user already exists, and rollback the changes. Because this is an update, the user must exist.
Update 2
I'm still trying to fix this issue, here the difference between a logged in user who's editing their password, and via password forget method (not logged in)
Logged in user changing password
Started PATCH "/admin/users/1" for 127.0.0.1 at 2013-08-13 16:12:07 +0200
Processing by Admin::UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"password"=>" [FILTERED]", "password_confirmation"=>"[FILTERED]"}, "id"=>"1"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'f1078c2b74f6b3b3c9950b87a5b927db3f2bffcd' LIMIT 1
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1(0.4ms)
BEGIN
User Exists (1.0ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'info#netventief.nl' AND "users"."id" != 1) LIMIT 1
SQL (1.6ms) UPDATE "users" SET "encrypted_password" = $1, "updated_at" = $2 WHERE "users"."id" = 1 [["encrypted_password", "$2a$10$F4p6N0va/TY2nKOiXOSQ7e23NnHPyDytQZ6EvhtGd7FJ2oTMVFbSS"], ["updated_at", Tue, 13 Aug 2013 16:12:07 CEST +02:00]](12.6ms)
COMMIT
Rendered admin/users/edit.html.slim within layouts/application (8.7ms)
Rendered partials/_favicon_styles.html.slim (0.3ms)
Rendered partials/_olderbrowser.html (0.0ms)
Rendered partials/_navigation.html.slim (2.6ms)
Rendered partials/_notification.html.slim (0.1ms)
Rendered partials/_footer.html.slim (0.1ms)
Completed 200 OK in 167ms (Views: 23.0ms | ActiveRecord: 17.3ms)
User who is forgotten the password and would enter a new password
Started PUT "/passwords/1?token=[FILTERED]" for 127.0.0.1 at 2013-08-13 16:58:45 +0200
Processing by PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]"}, "token"=>"[FILTERED]", "id"=>"1"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'b198361b098c1bf110a2171dd7f00258d9ca9240' LIMIT 1
CACHE
(0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."confirmation_token" = 'b198361b098c1bf110a2171dd7f00258d9ca9240' LIMIT 1
(0.3ms)BEGIN
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'info#netventief.nl' AND "users"."id" != 1) LIMIT 1
(0.2ms) ROLLBACK
Rendered passwords/edit.html.slim within layouts/application (1.4ms)
Rendered partials/_favicon_styles.html.slim (0.3ms)
Rendered partials/_olderbrowser.html (0.0ms)
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
Rendered partials/_navigation.html.slim (5.0ms)
Rendered partials/_notification.html.slim (0.1ms)
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '' LIMIT 1
Rendered partials/_footer.html.slim (0.5ms)
Completed 200 OK in 102ms (Views: 14.7ms | ActiveRecord: 2.0ms)
Still expect the Put/Patch method and all the cache alerts. This seems pretty the same to me .. I have tried to use the patch http method, but it didn't help.
Update 3
Also my controller code, its pretty much the same as Clearance::PasswordsController. Removed methods that are not called by my problem.
require 'active_support/deprecation'
class PasswordsController < ApplicationController
skip_before_filter :authorize, :only => [:create, :edit, :new, :update]
before_filter :forbid_missing_token, :only => [:edit, :update]
before_filter :forbid_non_existent_user, :only => [:edit, :update]
def edit
#user = find_user_for_edit
render :template => 'passwords/edit'
end
def update
#user = find_user_for_update
if #user.update_attributes( password: password_reset_params )
sign_in #user
redirect_to url_after_update
else
flash_failure_after_update
render :template => 'passwords/edit'
end
end
private
def password_reset_params
if params.has_key? :user
ActiveSupport::Deprecation.warn %{Since locales functionality was added, accessing params[:user] is no longer supported.}
params[:user][:password]
else
params[:password_reset][:password]
end
end
def find_user_by_id_and_confirmation_token
Clearance.configuration.user_model.
find_by_id_and_confirmation_token params[:id], params[:token].to_s
end
def find_user_for_edit
find_user_by_id_and_confirmation_token
end
def find_user_for_update
find_user_by_id_and_confirmation_token
end
def forbid_missing_token
if params[:token].to_s.blank?
flash_failure_when_forbidden
render :template => 'passwords/new'
end
end
def forbid_non_existent_user
unless find_user_by_id_and_confirmation_token
flash_failure_when_forbidden
render :template => 'passwords/new'
end
end
end
You should track down where the following SQL query is being triggered from:
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'info#netventief.nl' AND "users"."id" != 1) LIMIT 1
This is the line that is causing your save to fail. My guess is that you have a validation or some other callback on your User model that is firing when you are calling #user.update_attributes. The validation/callback is failing, which is causing the save to fail.
This is the line that is causing your save to fail. My guess is that you have a validation or some other callback on your User model that is firing when you are calling #user.update_attributes. The validation/callback is failing, which is causing the save to fail.

Github-like username url

I have this route that let me build custom url for users like
/thisismyname, and it works fine. But when I look at the log there is
something I don't like...
When I hit /gregory this is what is happenning:
1. Going to public_profile#public # Good
2. hitting /assets and trying to find a user with asset token # Not good
I thought my constraints would avoid this but it doesn't seem like it...
class PublicProfileConstraint
def self.matches?(request)
!['assets', 'admin'].include?(request.session[:token])
end
end
get "/:token" => "profiles#public", :as => :public_profile,
:constraints => PublicProfileConstraint
Here is the log:
Started GET "/gregory" for 127.0.0.1 at 2012-03-05 12:44:43 -0800
Processing by ProfilesController#public as HTML
Parameters: {"token"=>"gregory"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE
"users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE
"users"."token" = 'gregorymarcilhacy' LIMIT 1
Rendered profiles/_modal.haml (0.1ms)
....
Rendered profiles/show.haml within layouts/application (154.7ms)
Completed 200 OK in 431ms (Views: 174.0ms | ActiveRecord: 5.5ms)
... Redering js files ...
# I DONT WANT THIS
Started GET "/assets/" for 127.0.0.1 at 2012-03-05 12:44:45 -0800
Served asset - 404 Not Found (10ms)
Processing by ProfilesController#public as */*
Parameters: {"token"=>"assets"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE
"users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE
"users"."token" = 'assets' LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 312ms
... Rendering images ...
# AND I DONT WANT THIS
Started GET "/" for 127.0.0.1 at 2012-03-05 12:44:45 -0800
Processing by LandingController#landing as */*
User Load (0.3ms) SELECT "users".* FROM "users" WHERE
"users"."id" = ? LIMIT 1 [["id", 1]]
Rendered landing/landing.haml within layouts/landing (0.8ms)
Completed 200 OK in 288ms (Views: 23.5ms | ActiveRecord: 2.2ms)
You are searching request.session for the token, but this will always fail as that's the session store rather than the request parameters. You probably want the equivalent of params[:token] in the constraint class. The request object documentation indicates that request.path_parameters[:token] might contain the value you are looking for.

Rails, dirty objects causing rollbacks

I have the following:
class User < ActiveRecord::Base
before_update :guest_upgrade
def guest_upgrade
# If the user changed their email that means they were a guest, and are no longer.
# Likely triggered from the Registrations#Update controller
if self.email_changed?
self.guest = false
end
end
This is causing rollbacks, here is the log with the above in play:
Started POST "/users" for 127.0.0.1 at 2011-07-18 14:54:00 -0700
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x+u1DSDanU2QXK/q0=", "user"=>{"fname"=>"xxxxx", "lname"=>"xxxx", "email"=>"xxxxxxx#gmail.com", "password"=>"[FILTERED]", "remember_me"=>"1"}, "commit"=>"Create my account", "fb_access_token"=>"", "fb_uuid"=>""}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
SQL (0.1ms) BEGIN
User Load (0.5ms) SELECT "users"."id" FROM "users" WHERE ("users"."email" = 'xxxxxxx#gmail.com') AND ("users".id <> 5) LIMIT 1
SQL (0.2ms) ROLLBACK
Authentication Load (0.5ms) SELECT "authentications".* FROM "authentications" WHERE "authentications"."provider" = 'facebook' AND ("authentications".user_id = 5) LIMIT 1
Rendered layouts/_header.html.erb (3.9ms)
CACHE (0.0ms) SELECT "authentications".* FROM "authentications" WHERE "authentications"."provider" = 'facebook' AND ("authentications".user_id = 5) LIMIT 1
Rendered registrations/edit.html.erb within layouts/application (107.0ms)
Completed 200 OK in 484ms (Views: 111.7ms | ActiveRecord: 6.0ms)
Yet if I comment out the guest_upgrade it works fine:
Started POST "/users" for 127.0.0.1 at 2011-07-18 14:55:23 -0700
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxxx+u1DSDanU2QXK/q0=", "user"=>{"fname"=>"XXXX", "lname"=>"XXXX", "email"=>"xxxx#gmail.com"}, "commit"=>"Save Changes"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
SQL (0.1ms) BEGIN
User Load (0.4ms) SELECT "users"."id" FROM "users" WHERE ("users"."email" = 'xxxx#gmail.com') AND ("users".id <> 5) LIMIT 1
AREL (0.7ms) UPDATE "users" SET "fname" = 'XXXX', "lname" = 'XXXX', "email" = 'xxxx#gmail.com', "updated_at" = '2011-07-18 21:55:23.817142' WHERE "users"."id" = 5
[paperclip] Saving attachments.
SQL (37.9ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 780ms
Am I using the dirty objects incorrectly?
All I want to do is, when User is updated, if the user changes there email, change the user.guest field to false.
Suggestions? Thanks
I think I've had this problem before. I believe what's happening is it's returning false; try adding an explicit return like so:
if self.email_changed?
self.guest = false
return true
end
Check out the section marked Canceling Callbacks at ruby on rails.org api. It reads:
Canceling callbacks
If a before_* callback returns false, all the later callbacks and the
associated action are cancelled. If an after_* callback returns false,
all the later callbacks are cancelled. Callbacks are generally run in
the order they are defined, with the exception of callbacks defined as
methods on the model, which are called last.
I know I'm late but I hope this helps!

Resources