This is a big reason _not_ to use acts_as_row_secured. UserContext is
essentially a dirty hack to sneak session data references into the
ActiveRecord definition itself which violates MVC and forces you to
have to set global constants when using a model anywhere outside of a
controller. This technique is used in all over the place in ad hoc
PHP apps which is why it seems wrong to me.
Let me play devil's advocate here and take the contrary position to
this, giving reasons why you might want to break MVC in this
particular way in this particular case:
First, by doing this with acts_as_row_secured you enforce that some
UserContext is available during any model access. Although this gets
in the way of some simple manual testing (requiring you to have
contexts set all the time), by the same token, it enforces that you
can't 'fake' your unit tests: You don't get the choice of wrapping a
UserContext all the time -- if access security is paramount to you,
this is a painful, but enforced way of making sure you have it at all
time (including in all your testing).
Second, although this does break "classical" MVC (making the M reach
out to the C for the UserContext, or, put the other way, invisibly
injecting the UserContext from C down into M), this can be thought of
very naturally if you just forget about UserContext altogether; just
forget UserContext exits -- it's taken care of for you, by this hack,
and it (UserContext) becomes part of the metaobject protocol. So, if
you just forget that UserContext is a concept that you have to worry
about anylonger, then MVC is no longer broken.
Finally, even if we grant that this breaks MVC (that is, you can't
take my proposed stance of just forgetting about UserContext), hacking
the metaobject protocol to take account of contextual factors is a
well-accepted pattern in many (non-PHP) programming paradigms. One
thing that RoR offers is a well encapsulated way of doing this; PHP
does not, so, you're right that this is ad hoc and ugly in PHP, but
the same thing can be done in RoR in this conceptually clean way.
This is a very common, and very clean, pattern in Lisp engineering,
where working with the metaobject protocol is a well accepted meta-
pattern. This isn't to bias the issue, just to point out that just
because a pattern is ugly in language A, it needn't be ugly in
Language B, where B offers a clean way to do it.
'Jeff
[Full disclosures: a. I work with Tony, b. Although I'm not a highly
experienced Rails engineer, I *am* a highly experienced engineer in
many other paradigms OOP and classical paradigms, incl. Smalltalk and
Lisp. I'm engaging in this discussion out of real constructive
interest in learning; thus the devil's advocate stance.]