I wondering is there a way to represent model differently (or probably control access on fields level) depending on it’s (model instance) state and controller using it.
Example:
Imagine we have an Order model with product_id, count, price and status fields.
status could be one of: :new, :confirmed, :accepted, :cancelled, :delivered and :closed.
Application can access Order from, say, two controllers CustomerOrdersController and SellerOrdersController. So, CustomerOrdersController could create and edit orders. But able to change only count field. On the other hand SellerOrdersController could edit orders. But able to change only price field. I.e. it would be great if instance of Order class that CustomerOrdersController working with have no price= method. Same for count=(product=) and SellerOrderController.
Further more set of columns permitted to edit depends on status field (probably work for some state machine).
So, the question is: how would you do this in your app?
PS
I think about some ActiveModel proxy objects for ActiveRecord instances, but do not know actually will it work or not. Consider:
class CustomerOrderProxy < ActiveModel::Base end
class SellerOrderProxy < ActiveModel::Base end
class Order < ActiveRecord::Base
def wrap_proxy(controller_user)
controller_user == CustomerOrdersController ? CustomerOrderProxy(self) : SellerOrderProxy(self)
end
end
Another approach would be to do tons of checks and params validations inside controller actions, but I do not want to. I believe in “Fat model – skinny controller” 🙂
PPS
I know that ruby have plenty state machine plugins, but AFAI understand they define only transitions, not method set (i.e. representation) of the object.
Looks like I’ve found appropriate solution: in Ryan Bates’s screencast Dynamic attr_accessible
Update:
In Rails 3.1
update_attributes(params[:order], role)could be used. Check out rails api. Though it cannot be used to change access control according to object’s state.