Why Does My Rails Rollback When I Try to User.Save

Why does my rails rollback when I try to user.save?

Your user model probably has validations which are not satisfied. Since you've not posted those I'm unable to really solve your question. To make live easier you can debug why your user isn't willing to save.

Try running

user.errors.full_messages

which should give you a hint what's going wrong.

Rails rollback while saving model

License model contains two foreign key user_id and license_type_id

=> Which means before create License there must be a user who own this License as Rails 5 convention says user_id must exist

=> Also there must exist LicenseType as Rails 5 convention says license_type_id must exist

The rollback reasons can be investigated by following

license = License.new(license_types_id: LicenseType.first.id)
license.save
#Begin
#ROLLBACK
errors_stack = license.errors

errors_stack contains model level errors which causes rollback

To fix these rollback issue

user = User.first #or current_user
license = user.license.new(license_type_id: LicenseType.first.id)
license.save

Or

user = User.first #or current_user
license = License.new(license_type_id: LicenseType.first.id, user_id: user.id)
license.save

Or To create a User and assign the user a License # Alternative of after_create :create_assocs

new_user = User.new(...)
new_user.license.build(license_type_id: LicenseType.first.id)
new_user.save

Rollback happens when I update user model in Rails?

The SELECT 1 ... query inside the transaction looks like the query checking for uniqueness. And in fact, your model has a uniqueness validation. When there is no data inserted after this query then there is a high chance that this validation failed and therefore Rails rolls back all things done in the concept of this save operation.

That means you tried to create a user with a username that already exists in the database.

To see exactly what when wrong and to give the user feedback I suggest returning validation errors to the user. This could be done by changing your controller method to:

def update
user = User.find_by(id: params[:id])

if user.update(user_params)
render json: user, status: :ok
else
render json: user.errors, status: :unprocessable_entity
end
end

why rails rollback unexpected when i try to create a new user in the database?

In the create action, replace:

User.new(params[:id])

with:

User.new params.require(:user).permit(:name, :email, :password, :password_confirmation)

To get data passed to the active record model.


As for why it failed:

  • I guess you have a unicity validation on email
  • you pass no email (because wrong params)
  • you may already have an empty email in database
  • validation fails

Fun fact: it's a good example to have database ensure you have expected data (are null emails really allowed?)

rails console rollback on save

The thing is, the record doesn't contain a field called password, it has password_hash and password_salt, any time you try to save rails looks for the password field but can't find it, i'd say create a condition that tell rails when to look for a password, for example

validates :password, if: :password_required?
def password_required?
user.changes.include? :email # just an example
end

This will prevent asking for passowrd every time the user changes something minor in his account, and it will ask for the password if the user changes his email, you could add more options of course.

If you want to force the saving of the user in the time being, you could tell rails to skip validations

user.save(validate: false)

Also as a last note, it's better and safer to use a well developed and mature authentication gem like devise, it has all the features you'd need in any authentication.

Why does Rails rollback even though the model exists?

I think your validations are the issue. Password presence is validating on every update. Since User#password is nil and you don't have a password in your params, it fails.

class User < ApplicationRecord
has_secure_password
validates :password, presence: true, confirmation: true
end
>> User.create(email: 'test@user.com', password: '123456');
>> User.first.update!(email: 'test@user.com')
User Load (0.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
ActiveRecord::RecordInvalid: Validation failed: Password can't be blank

has_secure_password also adds its own validations.

https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password

If you want to customize password validations use

has_secure_password validations: false
# + your password validations

To get some ideas, you can take a look at how devise does validations:

https://github.com/heartcombo/devise/blob/v4.8.1/lib/devise/models/validatable.rb#L60



Related Topics



Leave a reply



Submit