Model validation when update_attributes in Rails

Asked

Viewed 1,254 times

1

I want to know how to validate my model for when @model.update_attributes(params) in my controller is called to return a possible error or false that seems to be the default returned by update_attributes.

Following the logic of fat models, I thought to put the validation in the model because it would lose my controller.

The question is how to implement this in the model so that my controller only continues with @model.update_attributes(params). And return false if validation does not pass.

Validation should only happen in the update.

  • I tried this validate :tem_stock, :before => :update , but the object is still saved even adding an error and returning false in the tem_stock method. Until without :before => :update the object is still saved. Just to put it in context, I’m trying to avoid updating a line_item from Spree if this line_item doesn’t have the product in stock. The stock in this case does not use the default Spree but a customization.

2 answers

2


Cassio, considering that you want to do this validation only in the update, you could do something like:

class Invoice < ActiveRecord::Base
  validate :active_customer, on: :update

  def active_customer
    errors.add(:customer_id, "is not active") unless customer.active?
  end
end

You can see the documentation of this, here: http://edgeguides.rubyonrails.org/active_record_validations.html#custom-methods

  • This is really the solution. I ended up coming to it by the guide. But I couldn’t solve my problem. In my case I have an Order model that has several Lineitem and the line items are updated by Order#update which somehow caused this validation of Lineitem did not work.

0

You can implemante the Active Record Validations.

Example:

You have a model called User with the attributes :name, :email, :password, in it you can add the validations:

class User < ActiveRecord::Base
    validates :name, presence: true
    validates :password, length: { minimum: 5 }
    validates :email, presence: true
end

And then in your update method you can do the following:

def
    @user = User.find(params[:id])

    respond_to do |format|
        if @user.update_attributes(params[:user])
            format.html # index.html.erb
        else
            format.json { render json: @user.errors, status: :unprocessable_entity }
        end
    end
end

The @user.errors Iré display validity errors.

I hope it helps :)

  • Opa @seujota, I edited the question. I need the validation to happen only when updating the model. Why among all validations I want this validation to prevent the update because it is critical.

  • @Cassiocabral you can keep the same format I proposed, then the moment you don’t want to use the validation you can "skip it" @user.save(:validate => false) if you still want other alternatives you can create validation methods in the model and use a callback like after_update for example.

  • It doesn’t work. I need something specific, a check on every update. Because I check if a value has changed, if it has changed I check if it can be modified according to the logic of the application. If true, it proceeds with the update normally. Something in the way of a custom method(http://edgeguides.rubyonrails.org/active_record_validations.html#custom-methods) but only valid when performing the update. The question of passing the validate does not suit and in case it would be ideal a before_validate call a custom_method. This model is a line_item, it is only saved after it has been updated, it is the rule.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.