How Do I Create a Conditional Setter Method

I’m trying to write a setter method in one of my models. Let me
explain the purpose quickly:

I have two objects in my model (that are stored in the database) that
I would like to be set as zero if a condition is true on model save.
I’d rather put this in the model and not as a database default because
I’d prefer there not to be a zero in the textfield by default for the
object in the form.

I have added the following to my model

attr_accessor :wrist_inches, :forearm_inches

and I’ve been trying this logic that hasn’t gotten me anywhere (at
least from the console). I can’t seem to actually write to the method
it just remains nil.

def wrist_inches=(wrist_inches)
@wrist_inches = “0” if male?
end

male? is a custom method for the model that returns true if the users
sex is marked as male.

If the above is not true it should just pass the numer that the user
has passed to the model.

I’ll be the first to admit that my grasp of the attr meta programming
is lacking, but I’m hoping someone can help me with my logic here not
to mention, if anyone has a way of exampling the concept of getter/
setter methods I’d be happy to listen.

Thanks,

Tim K.

On 24 Dec 2007, at 17:17, blaine wrote:

I have added the following to my model

attr_accessor :wrist_inches, :forearm_inches

don’t do that. It will clobber the accessors AR makes for you.

and I’ve been trying this logic that hasn’t gotten me anywhere (at
least from the console). I can’t seem to actually write to the method
it just remains nil.

def wrist_inches=(wrist_inches)
@wrist_inches = “0” if male?
end

You would need to use write_atribute instead of @foo= But perhaps this
would better be done in a before_save

Fred

From the Rails docs:

You can alternatively use self[:attribute]=(value) and self[:attribute]
instead of write_attribute(:attribute, value) and
read_attribute(:attribute)
as a shorter form.

For an example:

On Dec 24, 2007 9:17 AM, blaine [email protected] wrote:

I’m trying to write a setter method in one of my models.


http://www.rubyplus.org/
Free Ruby Screencasts

I appreciate both of you trying to assist a newbie here. Let me show
you what I tried… and if you could please tell me if I’m on the
right track, because nothing seems to be working…

I first tried a before_save action of like the following:

before_save :zero_if_user_is_male

def zero_if_user_is_male
if male?
write_attribute(:wrist_inches, 0)
wrist_attribute(:forearm_inches, 0)
end
end

That didn’t work… Then I tried the setter method again, like this:

def wrist_inches=(wrist_inches)
write_attribute(:wrist_inches, 0) if male?
end

def wrist_inches
read_attribute(:wrist_inches)
end

Where am I messing up here? Can I do validation on a before_save?
Like:

before_save :zero_if_male, :if => :male?

Am I addressing the attributes correctly?

Thanks,

Tim K.

Try these:

blaine wrote:

I first tried a before_save action of like the following:

before_save :zero_if_user_is_male

def zero_if_user_is_male
if male?
write_attribute(:wrist_inches, 0)
wrist_attribute(:forearm_inches, 0)
end
end

before_save :zero_if_user_is_male
def zero_if_user_is_male
if male?
self.wrist_inches = 0 if wrist_inches.nil?
self.forearm_inches = 0 if forearm_inches.nil?
end
end

That didn’t work… Then I tried the setter method again, like this:

def wrist_inches=(wrist_inches)
write_attribute(:wrist_inches, 0) if male?
end

def wrist_inches
read_attribute(:wrist_inches)
end

def wrist_inches=(wi)
if male? && wi.nil?
self[:wrist_inches] = 0
else
super
end
end


We develop, watch us RoR, in numbers too big to ignore.

Ok - it seems the setter method doesn’t work because I’m not actually
sending anything to that attribute. And no worries, I spent some time
looking up the super method… interesting…

Thank you Mark… it was me forgetting to address self…

Using the before filter worked perfect… but the setter method didn’t
work. Not that it’s a big deal, but I’m curious if you had any
thoughts why? Also what is super that you are calling in the else of
the condition?

Thanks,

Tim K.