Zach
By saying that models need the following case statement
def by_role(role
case role
when "associate"
....
when "admin"
...
end
your implying that the model is represented in a different way depending on
the role. So in your case of invoices the associate's view is different from
the administrators. If this is the case then you have identified two
distinct resources!
Currently you are representing these two resources with one url e.g.
/invoices
However if you think of these as seperate resources then you have two url's
/admin_invoices /associatie_invoices
Other url schems come fo mind /admin/invoices /invoices/admin etc.
Point is that you can implement these seperate resources in the standard
rails way and remove any need for case statements
class AdminInvoicesController
before_filter must_be_admin
def index
Invoices.find # specify admin criteria here
end
end
class AssociateInvoices
before_filter must_be_associate
def index
Invoices.find # specify associate criteria here
end
end
Andrew
2009/3/3 Zach Dennis <[email protected]>
> On Tue, Mar 3, 2009 at 12:32 PM, Pat Maddox <[email protected]> wrote:
> > On Mon, Mar 2, 2009 at 8:35 PM, Stephen Eley <[email protected]> wrote:
> >> On Mon, Mar 2, 2009 at 5:16 PM, Zach Dennis <[email protected]>
> wrote:
> >>>
> >>> Forgot to mention what we did do. We ended up with the following...
> >>>
> >>> def index
> >>> if user.has_role?("admin")
> >>> user.in_role("admin").invoices
> >>> elsif user.has_role?("associate")
> >>> user.in_role("associate").invoices
> >>> else
> >>> raise AccessDenied
> >>> end
> >>> end
> >>
> >> That seems sort of backwards to me. These aren't the user's invoices,
> >> right? They're just invoices which the user happens to be allowed to
> >> see? Chaining it this way makes it look like the invoices *belong* to
> >> the role, and seems put the user up front instead of the invoices.
> >> You also have conditional branching with hardcoded values, making the
> >> controller brittle, and some redundancy with the controller asking the
> >> model for a value and then passing the value right back to the model.
> >
> > Agreed. I have a similar example in a blog post:
> >
> http://www.patmaddox.com/blog/2008/7/23/when-duplication-in-tests-informs-design
>
> I agree I'm taking a step back to try to make two steps forward. The
> heart of the exploration is more than the conditional in the action
> (which simply states which roles are allowed to access that action, I
> just made it explicit rather than using a #restrict_to call). To me
> this discussion is about where the behaviour for a role should go and
> how-to access that behaviour.
>
> The flip side of this is that models end up with redundant conditional
> branches to do x for RoleA or y for RoleB (for every model thats
> affected by a Role). I would like to collapse these conditional
> branches and attempt a more polymorphic approach by extracting a class
> representative of each role, and simply calling the method in
> question. e.g:
>
> FiscalAssociate.new(user).invoices
> FiscalAdmin.new(user).invoices
>
> Rather than the following approach. Keep in mind that roles hardly
> ever are limited to one model. Consider having the case statement in
> 20 models. Where's the redundancy now?
>
> Invoice.by_role(<role_name>)
>
> def by_role(role
> case role
> when "associate"
> ....
> when "admin"
> ...
> end
>
>
> --
> Zach Dennis
> http://www.continuousthinking.com
> http://www.mutuallyhuman.com
> _______________________________________________
> rspec-users mailing list
> [email protected]
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users