ruby-on-railsrubymodelattr-accessible

Calling accessor methods from within a Model object in Rails


I have the following method in my model

def reset_review_status
   needs_review = true
   save
end

There is an attribute on the model called needs_review, however when I debug it, it saves it as a new variable. If I do self.needs_review=true, it works fine. I have no attr_accessible clause, although I do have one accepts_nested_attributes_for.

Any thoughts on why this might be happening?


Solution

  • When you define an attribute in ActiveRecord, the following methods are available

    # gets the value for needs_review
    def needs_review
    end
    
    # sets the value for needs_review
    def needs_review=(value)
    end
    

    You can call the setter using

    needs_review = "hello"
    

    but this is the same way you set a variable. When you call the statement within a method, Ruby gives higher precedence to variables assignment, thus a variable with that name will be created.

    def one
    # variable needs_review created with value foo
    needs_review = "foo"
    needs_review
    end
    
    one
    # => returns the value of the variable
    
    def two
    needs_review
    end
    
    two
    # => returns the value of the method needs_review
    # because no variable needs_review exists in the context
    # of the method
    

    As a rule of thumb:

    1. always use self.method_name = when you want to call the setter within a method
    2. optionally use self.method_name when a local variable with the same name exists in the context