Jesse Thompson
2008-Jun-09 05:14 UTC
ActiveRecord: Private or Readonly attributes? like attr_reader?
in a standard class, it is possible to allow reading of attributes while disallowing writing. I know ActiveRecord has an "attr_readonly" deal but it doesn''t stop you or throw an exception at the time of writing to the in-memory object, as I would like. It simply ignores the in-memory data, which would leave many on my staff scratching their heads as to why rails is countermanding their wishes. An exception thrown immediately would make it quite clear what''s gone wrong. Is this not a popular request? I''ve read that attr_readonly was itself a submitted patch. Would anyone be behind me if I made a patch for this idea? Would it be necessary? Thanks. :) - - Jesse Thompson Webformix, Bend OR --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Nathan Esquenazi
2008-Jun-09 10:51 UTC
Re: ActiveRecord: Private or Readonly attributes? like attr_reader?
There are probably a lot of ways to do this. Many of these ways are probably superior to this suggestion but one thought is to simply use metaprogramming to redefine attribute setter methods to throw an exception. For a single method, def some_attribute=(value) raise "You can''t set this attribute. It is read-only" end On a more meta level, self.column_names.each do |column_name| define_method("#{column_name}=") raise "You can''t set the attribute read-only ''#{column_name}''." end end This could also be easily done that patches activerecord::base to contain a macro such as attr_no_write :attribute1, :attribute2 and then simply use the metaprogramming shown above to throw it for those attributes. This could certainly be a plugin. It is also possible I totally missed a much better and more obvious way of achieving the same thing. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jesse Thompson
2008-Jun-09 18:05 UTC
Re: ActiveRecord: Private or Readonly attributes? like attr_reader?
Hello Nathan, thanks for taking a crack at this. I have already tried your first suggestion here. The trouble is that this pattern (def val=; raise ""; end) prevents the attribute from ever being written to, even from within the model itself. attr_reader and "private ''val=''" approaches in core ruby prevent setting the attribute from outside of the class, but allow it from within the class. I really do need to allow control over the attribute from within the class. In the "initialize" method for example, or when counters internally increment, or cached values internally need to be updated. If I have to I will look up how "attr_reader" is implemented and override that for ActiveRecord::Base and offer that as a plugin or a patch. But I just wanted to make sure that: A> this isn''t already somehow available a different way, and B> It''s a popular enough option. If this is not a popular pattern there must be a good reason; my view of the world may likely be out of whack. If it is a popular pattern I''m amazed it isn''t already available. Solomon''s adage "There is nothing new under the sun" really, really ought to apply here. If I have to write a new patch or plugin 3 hours into my first serious Ruby project, I''ve got to be overlooking something or leaving The Path somehow. I mean, who am I to find one of the most fundamental concepts from OOP 101 (private attribute setters) missing in the world''s most popular web framework, built upon the most zealously object oriented language since SmallTalk? I''ve got to be looking at something wrongly here. I''ve asked about this in irc with no more luck there. All I know is if I spend a day or two perfecting a patch or plugin, and only then does someone say "look, all you really should have done is (2 arbitrary lines of code)", I''ll go clinically mad. Also, should I ever be found meddling in such deep affairs if nobody else seems interested in this feature? Does my problem, and/or my paranoia about taking apart the engine to fix it, make any sense to anyone else here? ;) TIA for your wisdom! - - Jesse Thompson Webformix, Bend OR On Jun 9, 3:51 am, Nathan Esquenazi <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> There are probably a lot of ways to do this. Many of these ways are > probably superior to this suggestion but one thought is to simply use > metaprogramming to redefine attribute setter methods to throw an > exception. For a single method, > > def some_attribute=(value) > raise "You can''t set this attribute. It is read-only" > end > > On a more meta level, > > self.column_names.each do |column_name| > define_method("#{column_name}=") > raise "You can''t set the attribute read-only ''#{column_name}''." > end > end > > This could also be easily done that patches activerecord::base to > contain a macro such as > > attr_no_write :attribute1, :attribute2 > > and then simply use the metaprogramming shown above to throw it for > those attributes. This could certainly be a plugin. It is also possible > I totally missed a much better and more obvious way of achieving the > same thing. > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Pieter Visser
2008-Jul-09 17:22 UTC
Re: ActiveRecord: Private or Readonly attributes? like attr_reader?
> The trouble is that > this pattern (def val=; raise ""; end) prevents the attribute from > ever being written to, even from within the model itself.Hi Jesse, maybe you could use def some_attribute=(val) write_attribute(:some_attribute, val) unless *your readonly flag here* end Let me know if this solved your problem. Best Regards, Pieter Visser, Illusoft -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Ryan Bigg
2008-Jul-09 22:56 UTC
ActiveRecord: Private or Readonly attributes? like attr_reader?
If you don''t want users to be mass assigning the field, you can use attr_accessible and define all the fields that you DO want to be updated by the user. Any field not specified in this list will be unable to be assigned any value during mass assignation. If then later you decide somewhere your code that you do want to set the value, you can do: @user.update_attribute("some_field", 1) --~--~---------~--~----~------------~-------~--~----~ 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 rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---