Rails 4.2 ActiveAdmin 1.0.0.pre2 Cannot create a A

2019-09-02 17:46发布

问题:

Hi i am having a hard time figuring out this error. Yesterday i posted a question that my AcitveAdmin email field is always empty.Today i realised the problem is a bit bigger.

When i try to add a new user in the rails console the following happens.

>> au = AdminUser.new(email: 'sample@tom.com', password: "123456789", password_confirmation: "123456789")
=> #<AdminUser id: nil, email: "", encrypted_password: "$2a$10$Xt6EpJhtQ3d1v62KNZFUk.oi1RYe2gEBBeWVd/vApvi...",reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil>

>> au.valid?
AdminUser Exists (0.8ms)  SELECT  1 AS one FROM "admin_users" WHERE"admin_users"."email" = 'sample@tom.com' LIMIT 1
=> true

>> au.save
(0.8ms)  BEGIN
AdminUser Exists (1.1ms)  SELECT  1 AS one FROM "admin_users" WHERE "admin_users"."email" = 'sample@tom.com' LIMIT 1
SQL (3.5ms)  INSERT INTO "admin_users" ("encrypted_password","created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["encrypted_password","$2a$10$Xt6EpJhtQ3d1v62KNZFUk.oi1RYe2gEBBeWVd/vApviETIlUvpQ2q"], 
["created_at", "2015-10-21 13:57:44.081780"],["updated_at", "2015-10-21 13:57:44.081780"]]
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_admin_users_on_email"
DETAIL:  Key (email)=() already exists.
: INSERT INTO "admin_users" ("encrypted_password", "created_at","updated_at") VALUES ($1, $2, $3) RETURNING "id"
(1.2ms)  ROLLBACK
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_admin_users_on_email"DETAIL:  Key (email)=() already exists.

But i never used this email. I recently partitioned my database system. So now in productive environment i use a different database. But for development everything stayed the same. The one AdminUser in the admin_users table is still accessible and i can login with this one through the ActiveAdmin dashboard.

I found a similar problem here but the solutions does not work for me. Does anyone has any suggestion? Thanks to all in advance!

Update

It turned out there was a adminuser with a null address. So that is why i got the dublicate email field. I destroyed that user. Now i am able to add another adminuser. But the email field is still not written.

>> au = AdminUser.new(email: 'sample@tom.com', password: "123456789", password_confirmation: "123456789")
=> #<AdminUser id: nil, email: "", encrypted_password: "$2a$10$TWpMSdAxPl4vTFg54XvZcOe5Xkc7t4mf2Or7UlbkoA8...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil>

>> au.valid?
AdminUser Exists (25.6ms)  SELECT  1 AS one FROM "admin_users" WHERE "admin_users"."email" = 'sample@tom.com' LIMIT 1
=> true

>> au.save
(0.7ms)  BEGIN
 AdminUser Exists (0.8ms)  SELECT  1 AS one FROM "admin_users" WHERE "admin_users"."email" = 'sample@tom.com' LIMIT 1
 SQL (61.7ms)  INSERT INTO "admin_users" ("encrypted_password",
  "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"   
  [["encrypted_password", 
  "$2a$10$TWpMSdAxPl4vTFg54XvZcOe5Xkc7t4mf2Or7UlbkoA8W/n3rOGGwC"], 
  ["created_at", "2015-10-21 14:28:46.750437"], ["updated_at","2015-10-2114:28:46.750437"]]
   (18.0ms)  COMMIT
 => true

I also downgraded to ActiveAdmin 1.0.0.pre1 but the problem is still there.

回答1:

Context

ActiveAdmin uses something called Devise that handles creating an authenticated user model (named ActiveUser in AcitveAdmin's case). Devise is really nice because it handles adding and validating all the basic authentication fields like email, password, password_confirmation, etc.

OP problem

The OP had an issue of adding an attr_accessor :email which overwrote the Devise email field :( This meant that every time a user was created the email was always set to "".

But because of the complexities of the system, the ActiveRecord validation looked at the correct email field and said it was good. However, on save, the empty "" email was sent (which is still a string so doesn't invalidated the not null constraint. So an ActiveUser with a empty email was created. Then the next time a ActiveUser was created, a duplicate error was thrown (because another user with an email of "" was being inserted.

What to do if you have this problem

Make sure you don't have an accessor on the email field (or password/password_confirmation for that matter). And read the Devise guides if you need to do something fancy.