object.valid? returns false but object.errors.full_messages is empty

16,206

Solution 1

I had the same problem. At first I had such code in my model:

before_validation :set_some_param

def set_some_param
   self.some_param = some_value
end

After I changed this to:

before_validation :set_some_param

def set_some_param
   self.some_param = some_value
   true
end

I could see my errors.

Maybe you have something simular in your code?

Solution 2

Why don't you try @object.save!

Ruby should tell you what went wrong during the attempt to save the object.

Solution 3

Try looking at the results from:

subscription.errors.inspect

Solution 4

Ok I finally found the problem, thanks mates for the help.

I was overriding the valid? method in Subscription class to test another functionality which has not the same semantic. Big mistake, I juste renamed the method and it now works like a charm.

Share:
16,206

Related videos on Youtube

albandiguer
Author by

albandiguer

Updated on May 05, 2020

Comments

  • albandiguer
    albandiguer almost 4 years

    I'm confuse about objects that I can't save, simplified model is

    class Subscription < ActiveRecord::base
        belongs_to :user, :class_name => "User", :foreign_key => "user_id"
    has_many :transactions, :class_name => "SubscriptionTransaction" 
    
    validates_presence_of :first_name, :message => "ne peut être vide"
    validates_presence_of :last_name, :message => "ne peut être vide"
    validates_presence_of :card_number, :message => "ne peut être vide"
    validates_presence_of :card_verification, :message => "ne peut être vide"
    validates_presence_of :card_type, :message => "ne peut être vide"
    validates_presence_of :card_expires_on, :message => "ne peut être vide"
    
    attr_accessor :card_number, :card_verification
    
    validate_on_create :validate_card
    
        def validate_card 
        unless credit_card.valid?
            credit_card.errors.full_messages.each do |message|
                errors.add_to_base message
            end
        end
    end
    
    def credit_card
        @credit_card ||= ActiveMerchant::Billing::CreditCard.new(
            :type => card_type,
            :number => card_number,
            :verification_value => card_verification,
            :month => card_expires_on.month,
            :year => card_expires_on.year,
            :first_name => first_name,
            :last_name => last_name
        )
    end
    end 
    

    and in my subscription_controller

    if subscription.save
         # do something
    else
         debugger # means breakpoint where i try subscription.errors.full_messages
         # do something else
    end 
    

    I tried to use ruby-debug for this adding a breakpoint where i do some tests

    subscription.valid? #=> false 
    subscription.errors.full_messages #=> []
    subscription.save! #=> ActiveRecord::RecordInvalid (Validation failed:)
    

    which explains that ActiveRecord doesn't allow the save method. Unfortunately i can't know why the object is invalid.

    If you have any idea, thank you.

    • Mark Thomas
      Mark Thomas over 13 years
      Can you add your validators back in? It would also be nice to see a script/console session showing what you believe to be a valid subscription being created.
    • Marcel Jackwerth
      Marcel Jackwerth over 13 years
      When do you call subscription.errors.full_messages? After save/valid??
    • albandiguer
      albandiguer over 13 years
      Thank you for answers, Mark I add my validations. Marcel I try to display errors after save missed (I added debugger breakpoint in the controller in the example)
  • albandiguer
    albandiguer over 13 years
    save! generates the following exception ActiveRecord::RecordInvalid Exception: Validation failed: and sadly no more details
  • albandiguer
    albandiguer over 13 years
    Hi and thank you, as you can see we still can't see errors invalidating the object @subscription.errors.inspect #=> <... @errors={}>"
  • Samo
    Samo over 13 years
    If save! throws an exception, maybe you can put a rescue block in your code and inspect the exception for a full stack trace? Or I think there are other ways to get a full stack trace, I seem to remember doing something like @object.save! --trace but I can't remember exactly... If nothing of that sort works, je n'ai aucune idée mon ami :(
  • Anjan
    Anjan over 10 years
    Specifically from here: If the returning value of a before_validation callback can be evaluated to false, the process will be aborted and Base#save will return false. If ActiveRecord::Validations#save! is called it will raise a ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object.
  • Clash
    Clash over 10 years
    wow, I was going crazy with this... 2 hours wasted but finally your solution worked!
  • Steve Beer
    Steve Beer about 10 years
    I also stumbled upon this. My general solution for this problem is to just use assign_attributes(some_param: some_value) instead of directly assigning the attribute, because that will return a truthy value on success.
  • MothOnMars
    MothOnMars about 8 years
    5+ years later, this answer is still saving devs' sanity...thank you.
  • MBHNYC
    MBHNYC about 8 years
    Yup, only 1.5 hours wasted. We should add them all up!