Am 23.07.2009 um 04:57 schrieb Ease Bus:

> Felix,
>
> Wow!  Thank you very much for the detail and clear answer.  I knew  
> there was something wrong when I had to "throw" and "catch."  I read  
> that such construct is rare.  Following your advices, I have  
> rewritten the whole thing into validate and before_save, and  
> elevates the "save" operation out of the model.  The conditional  
> statement that I previously had buried in another model which was  
> used to "throw" now is in the validation.
>
> I did not expect that the original question would lead me to improve  
> a good portion of the code following the Rails good practices.   
> Thanks again.

I'm glad I could help :-)

> I still have this nagging question though:  How do I prevent an  
> attribute from being written to from outside the class?  In other  
> words, how do I make a setter function private so that only other  
> functions in the class can call it.

Well, If you are only concerned about the setter, have a look at  
attr_protected and attr_readonly. The first one prevents the attribute  
from being mass assigned, i.e. you can do  
my_instance.protected_attribute = "something", but not  
my_instance.update_attributes :protected_attribute =>  
"something", :other_attribute => "something else". The second should  
be quite clear, and as one would suspect allows you to set the  
attribute when first creating the element, but will silently ignore  
any subsequent attempts to update the attribute.

I guess if you really (really really really) wanted to keep someone  
from touching an attribute defined by a column of your model (all the  
columns in the table for your model get automagically converted to  
getters and setters) from outside the mode, you could do something like:

def dont_read_me
   raise whatever_exception # or even do nothing
end

def dont_read_me=(val)
   val # iirc a setter is assumed to return the value it gets fed, bad  
things may happen if it doesn't, or
   rais whatever_exception # that would really make sure anyone using  
the setter noticed you don't want touching the attribute
end

and you'ld have to use read_attribute and write_attribute in the rest  
of the model to get to those (and now that I had a look at the API,  
I'm not sure those 2 are private, so you'ld have to test it beforehand  
anyway...).

Felix

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to