Confused over Model attrbutes and @ prefix


#1

I’m confused about how attributes work in models. For example:

class Page < ActiveRecord::Base

attr_accessor :body

def foo
id # works
@id # won’t work IIRC
body # won’t work
@body #works
end

end

Why doesn’t everything work the same?

Joe


#2

somebody else can probably help you with a direct answer, but I think
“id”
is a reserved ActiveRecord attribute… but you’d probably want to check
the
docs.


#3

Dylan S. wrote:

somebody else can probably help you with a direct answer, but I think
“id”
is a reserved ActiveRecord attribute… but you’d probably want to check
the
docs.

I believe id is actually implemented as a method, because you can
override the primary key, but you still access it via “id”.

“body” doesn’t work because it could easily be a local variable in
method “foo”, so you can use self.body I believe. In fact, I think
self.id works as well.


#4

Dylan S. wrote:

somebody else can probably help you with a direct answer, but I think
“id”
is a reserved ActiveRecord attribute… but you’d probably want to check
the
docs.

It’s not just ‘id’, but any other field that comes from the database.

Joe


#5

Even more confused…

def before_create
self.file_extension = PAGE_FILE_EXTENSION # works
file_extension = PAGE_FILE_EXTENSION # doesn’t work
end

def body
File.open(path, ‘r’).read if File.file?(path) # works
end

def path
“#{CONTENT_PAGES}/#{id}.#{file_extension}” # works
end

AAIIEEE!

Joe


#6

On 2/15/06, Joe removed_email_address@domain.invalid wrote:

Even more confused…

def before_create
self.file_extension = PAGE_FILE_EXTENSION # works
file_extension = PAGE_FILE_EXTENSION # doesn’t work
end

The second assignment doesn’t work simple because to Ruby you’ve just
declared a new variable file_extension which will go out of scope when
this method returns.

Kent.
www.datanoise.com


#7

On Feb 15, 2006, at 7:13 PM, Joe wrote:

def before_create
self.file_extension = PAGE_FILE_EXTENSION # works
file_extension = PAGE_FILE_EXTENSION # doesn’t work
end

Ok, I just ran into the same thing.

You can execute method via their name only, or self.method_name.

However, if you do assignment, it takes a straight name as a
local variable, that’s why the second line in before_create
doesn’t work, a local variable file_extension is getting set.

def body
File.open(path, ‘r’).read if File.file?(path) # works
end

def path
“#{CONTENT_PAGES}/#{id}.#{file_extension}” # works
end

Both reads, therefore they work.


– Tom M.


#8

Makes sense.

I guess in the path method, Ruby/Rails would first try to find a local
var ‘file_extension’, and if one didn’t exist then it’d try accessing an
instance attribute/method?

def path
“#{CONTENT_PAGES}/#{id}.#{file_extension}” # works
end

Voodoo. I think there might be something to be said for requiring ()
after method calls, and referencing instance attributes with this
(self).

Joe


#9

I think part of the reason for this confusion is that there doesn’t seem
to be any clear explanation of when to use @attribute vs self.attribute.
This is also affected by class methods which people also seem to get
mixed up on.

I’m currently reading the Agile book and there is inconsistent usage of
self.attribute, @attribute and also self.class_method and
Class.class_method within various Model sample code. Other than the
explanation of defining class methods as self.method_name, there does
not appear to be any discussion of self vs. @

While the distinction seems to be much clearer with straight Ruby code,
it’s unclear what is the proper usage within Rails with all the built-in
class methods and attributes from ActiveRecord


#10

I’m not sure where the confusion is. If you’re using an AR object, it
automatically creates methods. You never do something like
@attribute, unless that attribute isn’t a database field. My only
guess is that you’re thinking of the Cart model, which is not an AR
class. It’s a straight Ruby class so you have to use the standard
Ruby syntax, no special methods are created.

Pat


#11

Guest wrote:

I think part of the reason for this confusion is that there doesn’t seem
to be any clear explanation of when to use @attribute vs self.attribute.
This is also affected by class methods which people also seem to get
mixed up on.

I’m currently reading the Agile book and there is inconsistent usage of
self.attribute, @attribute and also self.class_method and
Class.class_method within various Model sample code. Other than the
explanation of defining class methods as self.method_name, there does
not appear to be any discussion of self vs. @

While the distinction seems to be much clearer with straight Ruby code,
it’s unclear what is the proper usage within Rails with all the built-in
class methods and attributes from ActiveRecord

It seems to me that using @ should be reserved for those slightly more
hidden values of a class, and use self for everything else. I would
think using methods would be better in general because then if you can
make the change within that method (getter/setter). That is what makes
overriding column accessors in AR so easy.