kbob
kbob

Reputation: 45

rails changed? method is always false

I am trying to check in my model if a checkbox value was changed or not. If it was changed I want my method set_ip_setting to run in before_save but my x variable is always coming back as false even if I change the value. Why is it coming back as always false? I don't see what I am doing wrong

before_save :set_ip_setting, if: :check_my_ip
def check_my_ip
    x = self.sip.my_ip_changed?
    is_ip = self.sip.my_ip
    if x == true && is_ip == true
     return false
   elsif x == false && is_ip == true
     return false
  elsif x == true
     return true
   end 
end
def set_ip_setting
    if self.sip.try(:my_ip) == true 
      sip.nat = "yes"
      sip.invite = "yes"
    end
  end

EDITED I got my desired outcome by using previous_changes method but I think there is a cleaner way but here is what worked out for me

  def check_my_ip
    x = self.sip.previous_changes[:my_ip]
    off_to_on = [false, true]
    on_to_off = [true, false]
    is_ip = self.sip.my_ip ? 1 : 0
    if x.nil? && is_ip == 1
      return false
    elsif x == on_to_off
      return false
    end
    return true
  end

Upvotes: 2

Views: 505

Answers (1)

Schwern
Schwern

Reputation: 165200

Generally you do not write if x == true. In Ruby, true and false are distinct values. For example, 1 == true is false.

Instead, simply check if x or if !x.

def check_my_ip
  # Note that an explicit `self` is not necessary except when setting a value.
  x = sip.my_ip_changed?
  is_ip = sip.my_ip

  if x && is_ip
    return false
  elsif !x && is_ip
    return false
  elsif x
    return true
  end 
end

def set_ip_setting
  if self.sip.try(:my_ip)
    sip.nat = "yes"
    sip.invite = "yes"
  end
end

Your logic can be simplified, and implicit return used.

def check_my_ip
  x = sip.my_ip_changed?
  is_ip = sip.my_ip

  if is_ip
    false
  elsif x
    true
  else
    false
  end
end

Upvotes: 1

Related Questions