scambra / devise_invitable

An invitation strategy for devise
MIT License
2.66k stars 553 forks source link

Regression in validate_on_invite between 2.0.1 and 2.0.6 prevents record from being saved due to missing password #871

Closed uberllama closed 2 years ago

uberllama commented 2 years ago

Something has changed in a recent version such that passwords are not auto-generated if validate_on_invite is set to true.

2.0.1:

customer = Customer.new
customer.assign_attributes(email: "foo@example.com")
customer.invite!
# works hunky dory

2.0.6

customer = Customer.new
customer.assign_attributes(email: "foo@example.com")
customer.invite!
# ROLLBACK
customer.errors.full_messages # "Password can't be blank"
Thofeeq commented 2 years ago

In 2.0.1

lib/devise_invitable/models.rb

         if save(validate: false)
            self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
            deliver_invitation(options) unless skip_invitation
          end

in 2.0.6 - https://github.com/scambra/devise_invitable/commit/986f49b1625592c4622a99b6cfb6073b1a234b7c

lib/devise_invitable/models.rb

         validate = options.key?(:validate) ? options[:validate] : self.class.validate_on_invite
          if save(validate: validate)
            self.invited_by.decrement_invitation_limit! if !was_invited and self.invited_by.present?
            deliver_invitation(options) unless skip_invitation
          end

2.0.6 is no longer hard-coding validate to false and it's deriving the value from validate_on_invite config. If this config was set to true, the validation errors would happen whereas in previous version, validate was always set to false since this config, even if it was set, was not used.

scambra commented 2 years ago

If default controller is used, which calls class method, it will default to false, as it calls with validate: false option. Otherwise it defaults to follow setting. You can disable the setting if you don't need it, it can be set per model too if you have more than one model. Or calls with validate: false

customer.invite! nil, validate: false

mvz commented 2 years ago

This is a breaking change, right?

EDIT: On second thought, maybe it's a bugfix? In any case, the change was introduced in 2.0.6 and does not have a changelog entry unfortunately.

rylanb commented 2 years ago

Ahhh this is why my tests are failing. Thanks for the notes so I can fix!

scambra commented 2 years ago

I think it was a bugfix, although it shouldn't change default behaviour, when using the class method invite, as class method is providing validate option with false, as it worked before. So it would affect to custom code when calling the instance method invite, without providing a validate option.

I have updated the changelog