has_secure_password breaks collection save

2019-07-31 18:34发布

问题:

I am modifying a Rails app to use 'has_secure_password', but this has caused unexpected issues.

When a user creates an account, they specify name, email, password, password_confirmation, and are allowed to choose zero or more friends (see screenshot below).

In my controller, I am creating Friendship associations at the same time that the new user entity is saved. This is done by populating the 'friends' attribute of the creation parameters with an array of associated user objects.

def create
checked_params = user_params
if checked_params[:friends]
  checked_params[:friends].delete ""
  checked_params[:friends] = checked_params[:friends].map { |id| User.find(id) }
end

@user = User.new(checked_params)

respond_to do |format|
  if @user.save
    format.html { redirect_to @user, notice: 'User was successfully created.' }
    format.json { render action: 'show', status: :created, location: @user }
  else
    @friends = user_params[:friends]  # Replace with simple names and IDs
    format.html { render action: 'new' }
    format.json { render json: @user.errors, status: :unprocessable_entity }
  end
end
end

This method used to work, until adding the "has_secure_password" to my User model. Now, I get a generic "Friends is invalid" message whenever I save my model. Even knowing where this message is coming from would be helpful.

My project is hosted on GitHub

Here is a diff of the only changes I had to make in order to break my Friends saving.

diff --git a/Gemfile b/Gemfile
index 9beb2e3..2905724 100644
--- a/Gemfile
+++ b/Gemfile
@@ -36,7 +36,7 @@ group :doc do

 # Use ActiveModel has_secure_password
-# gem 'bcrypt-ruby', '~> 3.0.0'
+ gem 'bcrypt-ruby', '~> 3.0.0'

diff --git a/app/models/user.rb b/app/models/user.rb
index b5e6674..6d9cec9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -23,5 +23,6 @@ class User < ActiveRecord::Base
-  validates_confirmation_of :password
+
+  has_secure_password


diff --git a/db/migrate/20131018155801_create_users.rb b/db/migrate/201310181558
index 3b4a508..2a8cd85 100644
--- a/db/migrate/20131018155801_create_users.rb
+++ b/db/migrate/20131018155801_create_users.rb
@@ -3,7 +3,7 @@ class CreateUsers < ActiveRecord::Migration
     create_table :users do |t|
       t.string :name, null: false
       t.string :email, null: false
-      t.string :password, null: false
+      t.string :password_digest, null: false
       t.string :role, null: false

       t.timestamps

回答1:

The issue was simply that in my validations I had

validates :password, presence: true

Which is a duplicate of a validation performed within has_secure_password. No idea why this was causing the unexpected behavior I was seeing, but removing my duplicate validation resolved the symptoms.