asc99c
asc99c

Reputation: 3905

Rails model variable changing unexpectedly

Going mad here. Any pointers gratefully received!

I've got a Delivery model and I'm trying to add a method to update the delivery state, based on delivery lines. This function is defined within the model class, and delivery_state is one of the model attributes:

def updateDeliveryState
  expectedLines = DeliveryLine.where( :delivery_id => id,
                                      :line_state => 'EXPECTED' )
  logger.debug "State1: #{delivery_state}"

  if expectedLines.length == 0
    if delivery_state == 'EXPECTED' || delivery_state == 'RECEIVING'
      delivery_state = 'RECEIVED'               # commenting this line fixes it
      save
    end
  else
    logger.debug "State2: #{delivery_state}"
    if delivery_state == 'EXPECTED'
      logger.debug "Updating to receiving"
      delivery_state = 'RECEIVING'
      save
    end
  end
end

What I'm seeing in the log is that between the 2 logger.debug lines, the delivery_state has been cleared:

State1: EXPECTED
DeliveryLine Load (4.5ms)  SELECT "delivery_lines".* FROM "delivery_lines" 
WHERE "delivery_lines"."line_state" = 'EXPECTED' 
AND "delivery_lines"."delivery_id" = 227
State2:

If I comment out the line marked in the above code, it appears to work OK:

State1: EXPECTED
DeliveryLine Load (9.6ms)  SELECT "delivery_lines".* FROM "delivery_lines" 
WHERE "delivery_lines"."line_state" = 'EXPECTED' 
AND "delivery_lines"."delivery_id" = 227
State2: EXPECTED
Updating to receiving

However, I can see after refreshing that the delivery is still EXPECTED after this??

Upvotes: 1

Views: 90

Answers (2)

Michael Kohl
Michael Kohl

Reputation: 66837

To elaborate on my comment: it seems like you are creating a local variable in the if. Look:

class Foo
  attr_accessor :bar

  def test
    unless bar
      bar = 1
    end
  end
end

f = Foo.new
f.test
puts f.bar # empty line, bar is nil

Now let's make sure we call the setter:

class Foo
  attr_accessor :bar

  def test
    unless bar
      self.bar = 1
    end
  end
end

f = Foo.new
f.test
puts f.bar # prints 1

See: Why do ruby setters need “self.” qualification within the class?

Upvotes: 3

Tilo
Tilo

Reputation: 33732

can you try to use save(:validate => false) ?

Sometimes Rails has this nasty habit of silently failing validations and not saving.

You probably want to save your state no matter what... :)

Upvotes: 0

Related Questions