Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does ActiveRecord define methods compared to attr_accessor?

ActiveRecord seems to define instance methods differently than attr_accessor.

attr_accessor doesn't seem to define a super method for my new defined attribute:

class SomeClass
  attr_accessor :some_attribute

  def some_attribute
    super
  end
end

>> some_class = SomeClass.new
>> some_class.some_attribute
NoMethodError: super: no superclass method `some_attribute' for..

Whereas ActiveRecord definitely defines a super method:

class SomeClass < ActiveRecord::Base
  # some_attribute is now a column in our database

  def some_attribute
    super
  end
end

>> some_class = SomeClass.new
>> some_class.some_attribute
nil

Where is the difference between both? Is there a way to make attr_accessor define a super method?

EDIT: I still don't know how ActiveRecord defines it's methods, but I know how attr_accessor does it. Instead of super I can use @some_attribute since it stores the values in global variables of the same name: https://stackoverflow.com/a/4371458/586000

like image 743
jones Avatar asked Jan 18 '13 15:01

jones


People also ask

What does ActiveRecord base mean?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.

What is Attr_accessor?

attr_accessor is a shortcut method when you need both attr_reader and attr_writer . Since both reading and writing data are common, the idiomatic method attr_accessor is quite useful.

What does Attr_accessible do in Rails?

attr_accessible is a Rails method that allows you to pass in values to a mass assignment: new(attrs) or update_attributes(attrs) . Even if your form doesn't have a field for :price_off , if it's in your model it's available by default. This means a crafted POST could still set it.

What is Rails ActiveRecord?

What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.


1 Answers

When you use attr_accessor in your class that does not inherit from another class, there is, by definition, no method by the same name in a "parent" class. Therefore, super has nowhere to go to find a same-named method. (Well, your class inherits from Object, but Object does not define a method named some_attribute.)

On the other hand, ActiveRecord does define a getter and a setter for your attributes. Therefore, when you define them again in your class (that inherits from ActiveRecord::Base), then Ruby has somewhere to go (ActiveRecord::Base) when you invoke super.

Contrasting attr_accessor and the (many) methods that ActiveRecord generates for your table columns is a bit of an apples and oranges kind of question. ActiveRecord does all sorts of things with the attributes on the underlying table, including--but not limited to--creating getters and setters for the table columns.

(Note on the above: ActiveRecord works mostly by harnessing the power of method_missing, so many or most of the methods defined on your table attributes are actually implemented through the method_missing method. super does in fact invoke method_missing, if it exists, in parent classes, so that is how you can successfully invoke super on some_attribute when you inherit from ActiveRecord::Base.)

like image 61
scrozier Avatar answered Oct 15 '22 09:10

scrozier