That works only for conditions checking the id:
:user_id =>
current_user.idbut doesn't work for any deeper than that
As the docs says, accessing parent in ability (
https://github.com/ryanb/cancan/wiki/Nested-Resources )
can :manage, Task, :project => { :user_id => user.id }
Which is fine for filtering lists and :show in AS. But as for :update, or :delete, you're screwed since the code is all full of join everywhere:
https://github.com/ryanb/cancan/blob/master/lib/cancan/model_adapters/active_record_adapter.rb
join join join... switching for :includes looks like a looong way.
They could've done using :include instead of :join, since :include doesn't make :readonly. as explained here:
http://stackoverflow.com/questions/639171/what-is-causing-this-activerecordreadonlyrecord-error
So IMHO:
The problem doesn't affect all ruby. Just AS. Ways to fix it are:
1) AS :edit and :destroy shouldn't go through beginning_of_chain, or at least, use it just to check authorization and then fetch the clean record directly with no joins and complex sql, which may affect record's associations handling.
2) AS :edit and :destroy could use find_if_allowed(id).readonly(false) (if it works, not tested, RoR3-arel says it works).
3) as you can see in
https://github.com/ryanb/cancan/blob/master/lib/cancan/model_additions.rb , accessible_by is made for narrowing list of records. Suitable for :index.
joins aren't evil. In fact, they're more efficient than :includes which implies left outer join. But they're not suitable for writing records.
cheers,