1

I've tried to find the answer to this, but my Google-fu must be rusty or the keywords involved make results very noisy.

My understanding is that declaring a field in Mongoid creates accessor methods for that field (i.e. field and field=).

What I'm unclear on, as the usage seems to be mixed all over the place, is if and/or when I need to call self.field= to assign a value, and when that saves.

Example code:

class Product
  field state, type: String, default: "inactive"
  field sku, type: String

  def active?
    state == 'active'
  end

  def inactive?
    !active?
  end
end

It's clear that I can read a value defined by a Mongoid field without calling self.

But if I want to write a value in a field, do I need to call self? i.e.

# any difference between these?
def activate
  state = 'active'
end
def activate
  self.state = 'active'
end

TIA. This seems incredibly basic but for the life of me I can't find a clear answer.

AndrewS
  • 1,395
  • 11
  • 23

2 Answers2

4

When you are assigning a value to a property of an instance you need to use self. otherwise it creates a new local variable, in this case state that is deleted once it is out of scope (the end of the method). When reading a property it look in the current scope and then walks up the tree, in this case finding state on the instance.

infused
  • 24,000
  • 13
  • 68
  • 78
CWitty
  • 4,488
  • 3
  • 23
  • 40
  • 1
    Man I've been working as developer for 4 years and I had no idea about that calling when assigning a value to an attribute without `self.` it'd create an local variable in the current scope! Clearly I need to get some more deep understanding in Ruby! – André Herculano Apr 21 '15 at 12:35
0

Have a look at the following code it might help

class Product
  field state, type: String, default: "inactive"

  def activate
    p state #=> inactive
    p self.state #=> inactive
    state = 'active'
    p state #=> active
    p self.state #=> active

    # NOTE
    # in this example there is no difference between the 2... both refer to
    # the Product state field
  end

  def activate_state(state = 1)
    p state #=> 1
    p self.state #=> inactive
    state = 2
    self.state = 'active'
    p state #=> 2
    p self.state #=> active

    # NOTE
    # in this example there is a difference between the 2
    # cause in the scope of this method (activate_state) you have 2 state variables
    # and to distinguish between those 2 :
    # If you used self.state < you are referring to the Product.state field
    # If you used state < you are referring to the variable named state in the method
  end
end
a14m
  • 7,808
  • 8
  • 50
  • 67