Tableless ActiveRecord attribute and my aching head

I beat my head against a wall for almost 2 hours with this issue.

My first problem was easily solved. I wanted a class that could use
ActiveRecord’s validation capabilities but without using a table behind
it (I would be persisting setup information in the session, but the
initial setup parameters come from a user input form)

No problem…found this link which got me up and running

http://rails.techno-weenie.net/tip/2005/11/19/validate_your_forms_with_a_table_less_model

This was the class definition I ended up with:


class Setup < ActiveRecord::Base
def self.columns() @columns ||= []; end
def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s,
default, sql_type.to_s, null)
end


column :turn, :integer

def change_turn
if turn==0
turn = 1
else
turn = 0
end
end

end

ok…
now the head-banger. Any time I called the ‘change_turn’ method inside
my new class, the turn wouldn’t actually be changed. Oh, I would put
logger_debug statements inside the change_turn method itself and the
value WAS being changed, but the changes weren’t visible OUTSIDE the
class. Er?

It wasn’t until I changed the ‘change_turn’ method to look like this
that it started working properly:

def change_turn
if turn==0
self[:turn] = 1
else
self[:turn] =0
end
end

why!!!??? If I can reference the ‘turn’ attribute simply by calling it
'turn (as in ‘if turn==0’) then why cant I set the value by referencing
it the same way (by name)???
Is this in some way related to my abuse of ActiveRecord? Or is this
true of any Ruby class?

My head hurts and I am tired. I assume that I am missing something
basic here…

Any insight would be appreciated.

Try self[:turn]. I don’t think you’re affecting the state of your model.

View this message in context:
http://www.nabble.com/Tableless-ActiveRecord-attribute--and-my-aching-head-tf1982503.html#a5441400
Sent from the RubyOnRails Users forum at Nabble.com.

turn == 0 looks first for a local variable called turn, doesn’t find
it, so runs the turn method on the object.

turn = 0 (or turn = 1) defines a LOCAL variable called turn, that is
scoped to this method call. Because you want to run the turn method on
the object itself, use self.turn instead.

It is a bit confusing, but it does make sense. If you wrote a = 1 in
that method, you would not expect ruby to run the a method on the
object, you would expect it to create a local variable called a, which
is exactly what it does.

self.turn = 0 will work.

-Jonathan.