Right now I have a controller for "events" that belong to a specific
user. I only want the creator to be able to edit or delete the event.
I''ve got the proper foreign keys set up.
I''ve finally arrived at the point where I can take baby steps with
code, but looks like my first steps are in flagrant violation of the
DRY principle.
Here''s what I have so far in the "EventsController" and I
know it''s
ugly (but it works).
def update
@event = Event.find(params[:id])
if @event.user_id == session[:user] &&
@event.update_attributes(params[:event])
flash[:notice] = ''Event was successfully updated.''
redirect_to :action => ''show'', :id => @event
else
flash[:notice] = ''You do not have permission to edit.''
redirect_to :action => ''list''
end
end
def destroy
@event = Event.find(params[:id])
if @event.user_id == session[:user]
@event.destroy
redirect_to :action => ''list''
flash[:notice] = ''Event was deleted.''
else
flash[:notice] = ''You do not own this event.''
redirect_to :action => ''list''
end
end
What I would like to do is extract the "if @event.user_id
=session[:user]" kind of verification from controllers since I can
imagine calling this a lot as I add more models with a variety of
permissions?
Is there a better strategy to approach this?
Sam
Jay Levitt
2006-Feb-21 19:34 UTC
[Rails] Re: Abstracting ownership verification out of Controller
On Tue, 21 Feb 2006 22:06:06 +0900, SB wrote:> Right now I have a controller for "events" that belong to a specific > user. I only want the creator to be able to edit or delete the event.Seems like Bill Katz''s brand-new authorization DSL will help you, once somebody writes an implementation including permit_set: http://www.billkatz.com/authorization Jay Levitt
Ezra Zygmuntowicz
2006-Feb-21 20:34 UTC
[Rails] Abstracting ownership verification out of Controller
Sam-
Are you storing the whole user object in the session or just the
user.id? If you have the whole user object in thereyou can do it like
this instead to limit the fin and update to the user who is owner:
@event = session[:user].events.find(params[:id])
What that will do is add this to your where clause in :conditions :
AND user_id = whatever the session[:user].id is
If you dont have the user object in the session and just the id then
you can have a method set up that sets the current_user up:
def current_user
User.find(session[:user])
end
And then you would do your Event finder like this:
@event = current_user.events.find(params[:id])
Hope that helps
-Ezra
On Feb 21, 2006, at 5:06 AM, SB wrote:
> Right now I have a controller for "events" that belong to a
specific
> user. I only want the creator to be able to edit or delete the event.
>
> I''ve got the proper foreign keys set up.
>
> I''ve finally arrived at the point where I can take baby steps with
> code, but looks like my first steps are in flagrant violation of the
> DRY principle.
>
> Here''s what I have so far in the "EventsController" and
I know it''s
> ugly (but it works).
>
>
>
> def update
> @event = Event.find(params[:id])
> if @event.user_id == session[:user] &&
> @event.update_attributes(params[:event])
> flash[:notice] = ''Event was successfully updated.''
> redirect_to :action => ''show'', :id => @event
> else
> flash[:notice] = ''You do not have permission to
edit.''
> redirect_to :action => ''list''
> end
> end
>
> def destroy
> @event = Event.find(params[:id])
> if @event.user_id == session[:user]
> @event.destroy
> redirect_to :action => ''list''
> flash[:notice] = ''Event was deleted.''
> else
> flash[:notice] = ''You do not own this event.''
> redirect_to :action => ''list''
> end
> end
>
>
> What I would like to do is extract the "if @event.user_id =>
session[:user]" kind of verification from controllers since I can
> imagine calling this a lot as I add more models with a variety of
> permissions?
>
> Is there a better strategy to approach this?
>
> Sam
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
-Ezra Zygmuntowicz
Yakima Herald-Republic
WebMaster
http://yakimaherald.com
509-577-7732
ezra@yakima-herald.com
Francois Beausoleil
2006-Feb-21 22:20 UTC
[Rails] Abstracting ownership verification out of Controller
Hi ! 2006/2/21, Ezra Zygmuntowicz <ezra@yakima-herald.com>:> Are you storing the whole user object in the session or just the > user.id? If you have the whole user object in thereyou can do it like > this instead to limit the fin and update to the user who is owner:This article on my blog might be interesting: http://blog.teksol.info/articles/2005/10/21/model-serialization-in-session Bye ! -- Fran?ois Beausoleil http://blog.teksol.info/
Thank you all for the helpful suggestions, it definitely set me in the
right direction.
Yes, I did read all the resources suggested and it certainly gives me
an indication of what''s ahead.
I ended up using "before_filter" to accomplish this. Right now
it''s
right in the controller but if it crops up in other controllers, I
might try to get it into "application.rb".
Since I''m building up from scratch, I''d rather keep dependency
on
libraries and plugins to a minimum since I need to learn rails at the
same time rather than rush something out the door or read third party
code that''s beyond me.
One thing that throws me off with plugins, is that any given plugin
might represent a couple styles of coding. This can be confusing for
a beginner.
Here''s how I rewrote my code:
before_filter :verify_permission, :only => [:edit, :update, :destroy]
def update
if @event.update_attributes(params[:event])
flash[:notice] = ''Event was successfully updated.''
redirect_to :action => ''show'', :id => @event
else
redirect_to :action => ''list''
end
end
def destroy
@event.destroy
redirect_to :action => ''list''
flash[:notice] = ''Event was deleted.''
end
private
def verify_permission
@event = Event.find(params[:id])
if @event.user_id == session[:user]
return true
else
flash[:notice] = ''You do not have permission for this
event.''
redirect_to :action => ''list''
end
end
Basically, I restored "update" and "destroy" to what it was
before
only taking out "@event = Event.find(params[:id])" since it was now
part of "verify_permissions".
It gives me a warm feeling to post something on this list before bed
and wake up to see responses. Now I know how the shoemaker felt when
the elves came to the rescue.
And now for another session of solitary Subversion tag...
Sam
Bill Katz
2006-Feb-22 07:57 UTC
[Rails] Re: Abstracting ownership verification out of Controller
On 2/21/06, Jay Levitt <jay+news@jay.fm> wrote:> > On Tue, 21 Feb 2006 22:06:06 +0900, SB wrote: > > > Right now I have a controller for "events" that belong to a specific > > user. I only want the creator to be able to edit or delete the event. > > Seems like Bill Katz''s brand-new authorization DSL will help you, once > somebody writes an implementation including permit_set:Actually, the current plugin lets you handle Sam''s case pretty easily, even without permit_set. The permission check would be handled by a user_has_role? method in the Event model class. We hardwire a ''moderator'' role into the Event model. class Event < ActiveRecord::Base def user_has_role?( user, role ) return true if role == ''moderator'' and self.user_id == user.id false end end Then his controller looks like this: class EventController < ApplicationController permit "moderator of :event", :only => [:edit, :update, :destroy] def edit ... end ... end This works because the "event" in the permission expression is checked against @event, any :event hash, and finally, if params[:id] is not nil, it uses Event.find(params[:id]). This is an added convention that facilitates standard use. I''ve just started working with Ezra on refining the authorization DSL, and we may decide to make things more explicit. But right now, the plugin at http://www.billkatz.com/authorization will support authorizations like the above example. -Bill -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060222/4ec47ea0/attachment.html