starterkits/rails4-starterkit

RailsAdmin cannot edit multiple users.

Opened this issue · 18 comments

Setup Rails4-Starterkit, sign up as a user. Then signup as another User. When I go to RailsAdmin, click Users, editing the first user, click save. Everything is fine so far. but when I try to edit the second user in RailsAdmin, click save, this error appears:

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "users_pkey" DETAIL: Key (id)=(1) already exists. : UPDATE "users" SET "confirmation_token" = $1, "current_sign_in_at" = $2, "first_name" = $3, "id" = $4, "image_url" = $5, "is_admin" = $6, "last_name" = $7, "last_sign_in_at" = $8, "unconfirmed_email" = $9, "unlock_token" = $10, "updated_at" = $11 WHERE "users"."id" = 2

Can you let me know how to fix this?
Thanks,

Just an update on this issue. This only happens when you log into RailsAdmin as one user, tries to edit the profile of another User. This error message will appear when you try to save the edit.

+1

Same error if you try to use RailsAdmin to create a new user.

+1
same problem

This looks like a Devise issue that probably needs some extra code to work around.

In the meantime, give this a try and let me know if it helps

rails console

ActiveRecord::Base.connection.tables.each { |t|     ActiveRecord::Base.connection.reset_pk_sequence!(t) }

From http://stackoverflow.com/questions/24957863/devise-primary-key-error-on-postgresql-heroku-rails-4

Tried this. It didn't seem to work. still giving the same error. Anything else I can do?

I see the same behavior. It seems to be 100% reproducible in PostgreSQL with the bundled version of RailsAdmin. There's an open issue for RailsAdmin on this.

Editing the current user works because RailsAdmin (or Rails?) ignores values that are not changing when building the UPDATE SQL statement. For other users, it includes all values from the form, including the user_id which violates Postgres's pkey constraint. You can't update a pkey to a value that already exists. Even if it's the same row.

Bottom line, this will require some hardcore debugging in RailsAdmin to figure out what's going on.

I'll try to squeeze in some time this week to poke around.

There's an issue with CanCan and RailsAdmin integration. CanCan (or CanCanCan) is resetting the user_id or user.id to the current_user.id on edit.

I'll work on a fix.

+1
This problem is reproducible on both PostgreSQL & MySQL

+1

Any luck with this one? Besides this, this app works amazingly well. Thank you for developing such a great product!

any updates with this error?
Users need to login to console to reset their password.

UPDATE: Scratch what I said @simple10 is right, it is calling current_user.id to create the problem. The question is, is this a CanCan problem to fix or a RailsAdmin?

Two things about the error in my debugging efforts. It seems that something is either calling nil.id or User.first.id Each user I try to update, it is trying to use id=4.

This means I can update the user with the id 4, but I get errors for any other users.

Success for User #4

Started PUT "/admin/user/4/edit" for [FILTERED] at 2015-01-22 17:25:30 +0000
Processing by RailsAdmin::MainController#edit as HTML
  Parameters: {
    "utf8"=>"✓", 
    "authenticity_token"=>"[FILTERED]", 
    "user"=>{"first_name"=>"[FILTERED]", "last_name"=>"[FILTERED]", "image_url"=>"", "email"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "reset_password_sent_at"=>"[FILTERED]", "remember_created_at"=>"January 22, 2015 16:49", "sign_in_count"=>"2", "current_sign_in_at"=>"January 22, 2015 16:49", "last_sign_in_at"=>"January 22, 2015 16:17", "current_sign_in_ip"=>"[FILTERED]", "last_sign_in_ip"=>"[FILTERED]", "confirmation_token"=>"", "confirmed_at"=>"", "confirmation_sent_at"=>"", "unconfirmed_email"=>"", "failed_attempts"=>"0", "unlock_token"=>"", "locked_at"=>"", "is_admin"=>"1", "authentication_ids"=>["", ""]}, 
    "return_to"=>"[FILTERED]", 
    "_save"=>"", 
    "model_name"=>"user", 
    "id"=>"4"}
Redirected to [FILTERED]
Completed 302 Found in 40ms (ActiveRecord: 7.4ms)

Notice the "id"=>"4"

Failure for User #6

Started PUT "/admin/user/6/edit" for [FILTERED] at 2015-01-22 17:39:19 +0000
Processing by RailsAdmin::MainController#edit as HTML
  Parameters: {
    "utf8"=>"✓", 
    "authenticity_token"=>"[FILTERED]", 
    "user"=>{"first_name"=>"[FILTERED]", "last_name"=>"", "image_url"=>"", "email"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "reset_password_sent_at"=>"[FILTERED]", "remember_created_at"=>"", "sign_in_count"=>"1", "current_sign_in_at"=>"January 22, 2015 16:49", "last_sign_in_at"=>"January 22, 2015 16:49", "current_sign_in_ip"=>"[FILTERED]", "last_sign_in_ip"=>"[FILTERED]", "confirmation_token"=>"", "confirmed_at"=>"", "confirmation_sent_at"=>"", "unconfirmed_email"=>"", "failed_attempts"=>"0", "unlock_token"=>"", "locked_at"=>"", "is_admin"=>"1", "authentication_ids"=>["", ""]}, 
    "return_to"=>"[FILTERED]/admin/user/6", "_save"=>"", 
    "model_name"=>"user", 
    "id"=>"6"}
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "users_pkey"
DETAIL:  Key (id)=(4) already exists.
: UPDATE "users" SET "first_name" = $1, "last_name" = $2, "image_url" = $3, "confirmation_token" = $4, "unconfirmed_email" = $5, "unlock_token" = $6, "current_sign_in_at" = $7, "last_sign_in_at" = $8, "id" = $9, "updated_at" = $10 WHERE "users"."id" = $11
Completed 500 Internal Server Error in 1033ms

ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "users_pkey"
DETAIL:  Key (id)=(4) already exists.
: UPDATE "users" SET "first_name" = $1, "last_name" = $2, "image_url" = $3, "confirmation_token" = $4, "unconfirmed_email" = $5, "unlock_token" = $6, "current_sign_in_at" = $7, "last_sign_in_at" = $8, "id" = $9, "updated_at" = $10 WHERE "users"."id" = $11):

Notice the DETAIL: Key (id)=(4) already exists.

Any update on this issue? It seems problem is with cancan(can) integration. Here is the work around in the mean time ...

  1. remove cancan as authorization mechanism from rails admin config.
  2. Use following code
config.authorize_with do
      redirect_to main_app.root_path unless warden.user.is_admin?
end

Looking like this workaround isn't effective now?

+1 Still looking for a fix on this.

It seems the workaround is still effective, but may produce a similar duplicate key error on unlock_token, i.e.
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_unlock_token" DETAIL: Key (unlock_token)=() already exists...

If this is the case, the easiest workaround for now seems to be to hide the offending field... In rails_admin.rb add

config.model 'User' do
    exclude_fields :unlock_token
end

This stackoverflow question appears to get at the underlying cause.

Hi, guys! Not sure if you're still interested, but I've found some workaround:
The following line in my ability.rb caused this issue: can :manage, User, id: user.id
For admins it was: can :manage, User if user.super_admin?

Changing the first line to can :manage, User, id: [user.id] solved this problem. And the ability is seems to be checked properly.