Gaius,

I applaud your desire to be safe with your user's information and
protect them from inadvertent programming errors. On my website, we
have a forum where sensitive matters are frequently discussed and so
we provide our users the option of posting anonymously. Of course, we
still need to know who posted it so that they can edit it later so I
had a similar conundrum that you're facing now. I didn't want to ever
let a developer accidentally reveal their identity when the anonymous
flag was set on their post. So I did little meta-programming to allow
me to make the user and user_id nil when the post was anonymous, but
still have access to the information through aliased methods if we
needed it.

http://gist.github.com/8654

Ruby on rails is great, but so is Ruby itself, and with a little
diligence, we can bend the world to our will to achieve a desired API.

-chris

P.S. For those not inclined to click through here's the rough sketch:
# == Schema Information
#
# Table name: posts
#
#  id                  :integer(11)     not null, primary key
#  user_id             :integer(11)
#  anonymous           :boolean(1)
#  ...
class Post < ActiveRecord::Base
  extend Anonymizer

  belongs_to :user
  anonymize_method :user
  anonymize_attribute :user_id
end

>> p = Post.find(:first, :conditions => {:anonymous => true})
=> #<Post id: 31, ... >
>> p.user
=> nil
>> p.user_id
=> nil
>> p.user_id_without_anonymous
=> 1234
>> p.user_without_anonymous
=> #<User id: 1234, ... >

On Sep 3, 1:06 pm, "James Rosen" <[EMAIL PROTECTED]> wrote:
> acechase: I think your case is different, but extremely close to the
> issue I'm getting at.  Thank you for bringing it up.
>
> Koz: are you prepared to argue that Ruby shouldn't have private
> methods at all because programmers can get around them with __send__?
> I want to make a method private so other programmers don't do stupid
> stuff.  I want it to be one more thing in the way of writing insecure,
> unreliable code.  There's no such thing as bulletproof code, but if I
> can add more padding without adding conceptual weight, I'm all for it.
>
> Also, I'd just like Rails Models to act like normal Ruby Objects.
>
> -Gaius
>
> On Wed, Sep 3, 2008 at 12:27 PM, acechase <[EMAIL PROTECTED]> wrote:
>
> > This is slightly tangential, but since we're on the subject, I'd like
> > to point out a related issue with private methods. It's early, and I'm
> > still working on my first cup of coffee, so please just ignore me if
> > I'm too off topic here :). The problem I am seeing is that a private
> > method works as expected when called directly on an object, but when
> > the object is accessed through an association_proxy 'private' is
> > ignored (because the association_proxy is 'send'ing on
> > method_missing).
>
> > Here's an example:
>
> > Class User < AR::Base
> >  private
> >  def secret_stuff ; "foo" end
> > end
>
> > Class Purchase < AR::Base
> >  has_one :user
> > end
>
> >>> User.first.secret_stuff
> > => NoMethodError: private method `secret_stuff' called for #<User:
> > 0x3d446dc>  # as expected
> >>> Purchase.first.user.secret_stuff
> > => "foo"  # d'oh!
>
> > Because the association_proxy does a blind send, the privacy check is
> > bypassed. When I first came across this, it really threw me for a loop
> > -- in one context my 'private' declaration was working fine and dandy,
> > and in another, it was being ignored! I wanted to use 'private'
> > because I had just modified my class in such a way that it made sense,
> > encapsulation-wise, to only have the class itself access the
> > particular method. I wasn't looking for true protection against
> > malicious code, I just wanted to verify my encapsulation properties
> > and find code that was violating those properties. In the end I
> > decided it wasn't worth the effort to make the two code paths behave
> > the same so instead I did a manual code comb to find outside classes
> > who were accessing my private method.
>
> > So, I guess I'm just offering this as another data point. It's another
> > place where the rails metaprogramming slightly modifies the expected
> > behavior of the underlying code. I don't think this is a major problem
> > or anything, just thought it fit in with the current topic. Maybe this
> > behavior is covered in the docs and I just missed it?
>
> > Cheers,
> > acechase
>
> > On Sep 3, 12:37 am, "Michael Koziarski" <[EMAIL PROTECTED]> wrote:
> >> > No, sorry.  I'm trying to _truly_ make an attribute private.  I want
> >> > nobody but my instance (self) to be able to access this attribute.
> >> > There's nothing like attr_private to my knowledge, though, so I
> >> > declared private methods.
>
> >> I'd question *why* you want that to be completely private, what is it
> >> you're hoping to achieve.  Users of your code will *always* be able to
> >> call your method, there's simply no way for you to stop them:
>
> >> @object.__send__(:your_secret_method) # PWN3D!!!!
>
> >> There's currently no way to mark an attribute as private, and we could
> >> probably add that as an enhancement, but I'm a little confused what
> >> the use case is.
>
> >> --
> >> Cheers
>
> >> Koz
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" 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-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to