I have a Rails 3 site I’m working on that has users who operate on “documents.”
If each document had a user_id then for the edit method in my document controller I could restrict results to documents owned by the current user with something like:
@doc = current_user.documents.find(params[:id])
respond_with(@doc)
Unfortunately, it’s not that simple. Each user can have a relationship with a document by means of an intermediate “subscription” – they can be the owner, an editor, or a reader.
So now, in my edit method I want to be able to restrict the retrieved document to those who are an owner or an editor. How do I do this? Currently I have a scope in my Document model like:
scope :editable_by, lambda { |user| joins(:subscriptions).where("user_id = ? AND (subscriptions.role = ? OR subscriptions.role = ?)", user.id, Subscription::ROLES['owner'], Subscription::ROLES['editor']) }
so that I can then go in my edit method:
@doc = Document.editable_by(current_user).find(params[:id])
Is there a nicer way?
I don’t think you’ll find a nicer way. For example, I tend to use CanCan for authorization, which only provides built-in helper methods if your model has an attribute indicating access rights (e.g. an
owner_id).Otherwise, you still have to implement a scope or a method on your model. So unless I’m mistaken, you’ll be hard pressed to find a better way than what you currently have.