[Rails] Design question - integrating light-weight authorization
Gavin Sinclair
gsinclair at soyabean.com.au
Wed Nov 24 10:32:11 GMT 2004
[I accidentally replied to Chris, not the list. Probably nobody else
is interested, but it might be good for the archives.]
On Wednesday, November 24, 2004, 6:43:43 PM, Chris wrote:
> This might be more of an MVC design pattern question than a
> Rails-specific question, but I'm sure someone out there will be
> willing to help out.
> I have a number of pages that should render differently based on the
> authentication state of the user (much of the content can be viewed
> even if unauthenticated) and the role of the user. Usually this means
> that certain edit fields / buttons won't be displayed if the user
> doesn't have privs to do so.
> I'm struggling with the right way to represent this. Should I be
> using a single view for these pages with conditional hiding of certain
> portions of the rendered page? Or should I be using different views
> for each class of user, with appropriate render calls from the
> controller?
I've been experimenting with this, and have used two techniques so
far: support from the helper module, and partial views.
The first approach, support from the helper module, looks like this:
# view (excerpt)
<%= link(:edit_details) %>
# helper (excerpt)
def link(target)
case target
when :edit_details
if logged_in?
link_to :action => 'edit'
end
when ...
end
end
As far as the view is concerned, it _always_ shows the "edit details"
link. But it uses the helper to create that link, and the helper is
smart about whether the link should actually be shown. If logged_in?
is false, the link() method returns nil, which appears as nothing in
the final screen.
The second approach, partial views, looks like this:
# view (excerpt)
<% if logged_in? %>
<%= render_partial 'logged_in_table', @data %>
<% else %>
<%= render_partial 'anonymous_table', @data %>
<% end %>
The partials are files named _logged_in_table.rhtml and
_anonymous_table.rhtml respectively. They both look like this:
<div class="data_table">
<table>
<% for d in @data %>
...
<% end %>
</table>
</div>
The ... in the partial above obviously contains different things for
the logged in partial and the anonymous partial. The point is, they
have the same structure, and both use the @data variable, which the
containing view must pass on.
You mentioned another approach, rendering different views from the
controller, which I have thought about but not tried. Having tried
the others, though, I think the this approach might actually suit my
needs better.
I don't think there's a single right answer. None of these techniques
smell bad to me; it's just a matter of working out how much needs to
change with each state, and working out how much HTML code you can
factor out.
Just like you, my session state is not merely binary (logged in or
not), even though my examples above don't show that. When you
introduce subtleties like user roles, you obviously need a subtle
approach. Calling entirely different view files from the controller is
certainly not subtle, so you should consider the other approaches.
Please note that I'm a complete novice at this. It just happens I've
been dealing with the same issue as you, so I hope this reply has been
useful.
Cheers,
Gavin
More information about the Rails
mailing list