One of these days I''ll figure this out, but in the meantime help me be a better programmer by eliminating some excess code: I''m trying to check to see if somebody trying to view/edit/update a product is the owner. In my scaffold I have this code that works: def edit @owner = Product.find(params[:id].to_i) if @owner.user_id == @user.id @product = Product.find(params[:id]) else flash[:notice] = ''Sorry, you''re not the owner.'' redirect_to :action => ''list'' end end Ok, so to simplify it, I wrote a private method called confirm_user: def confirm_owner @owner = Product.find(params[:id].to_i) unless @owner.user_id == @user.id flash[:notice] = ''Sorry, you''re not the owner.'' redirect_to :action => ''list'' end end Now, how can I call this in my edit? I tried to use a before_filter within my edit function but rails didn''t like that saying before_filter is an undefined method: def edit before_filter :confirm_owner @product = Product.find(params[:id]) end Any suggestions on how to do this please? -- Posted via http://www.ruby-forum.com/.
You''re actually 98% of the way there. All you''re missing is the place to put the before_filter method call. It goes just below the Class line of your Controller, not inside any of the Controller''s Actions, as you have it in your email below. Move the before_filter to the top of your Class definition, outside all the actions, and you should be all set. -Brian On Apr 21, 2006, at 06:25 PM, Vince W. wrote:> One of these days I''ll figure this out, but in the meantime help me > be a > better programmer by eliminating some excess code: > > I''m trying to check to see if somebody trying to view/edit/update a > product is the owner. In my scaffold I have this code that works: > > def edit > @owner = Product.find(params[:id].to_i) > > if @owner.user_id == @user.id > @product = Product.find(params[:id]) > else > flash[:notice] = ''Sorry, you''re not the owner.'' > redirect_to :action => ''list'' > end > end > > Ok, so to simplify it, I wrote a private method called confirm_user: > > def confirm_owner > @owner = Product.find(params[:id].to_i) > unless @owner.user_id == @user.id > flash[:notice] = ''Sorry, you''re not the owner.'' > redirect_to :action => ''list'' > end > end > > Now, how can I call this in my edit? I tried to use a before_filter > within my edit function but rails didn''t like that saying > before_filter > is an undefined method: > > def edit > before_filter :confirm_owner > @product = Product.find(params[:id]) > end > > Any suggestions on how to do this please? > > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Vince W. wrote:> One of these days I''ll figure this out, but in the meantime help me be a > better programmer by eliminating some excess code: > > I''m trying to check to see if somebody trying to view/edit/update a > product is the owner. In my scaffold I have this code that works: > > def edit > @owner = Product.find(params[:id].to_i) > > if @owner.user_id == @user.id > @product = Product.find(params[:id]) > else > flash[:notice] = ''Sorry, you''re not the owner.'' > redirect_to :action => ''list'' > end > end > > Ok, so to simplify it, I wrote a private method called confirm_user: > > def confirm_owner > @owner = Product.find(params[:id].to_i) > unless @owner.user_id == @user.id > flash[:notice] = ''Sorry, you''re not the owner.'' > redirect_to :action => ''list'' > end > end > > Now, how can I call this in my edit? I tried to use a before_filter > within my edit function but rails didn''t like that saying before_filter > is an undefined method: > > def edit > before_filter :confirm_owner > @product = Product.find(params[:id]) > end > > Any suggestions on how to do this please?In your controller, not in your action, try: before_filter :confirm_owner, :only => [:view, :edit, :update] That will constrain the filter to only the view, edit and update actions. And you only need to say it once, not even in each action. -- Posted via http://www.ruby-forum.com/.
What you are saying makes sense, and I''ve incorporated that into my code: class PostController < ApplicationController include AuthenticatedSystem before_filter :login_required, :find_user, :confirm_owner, :only => [:edit] but when I put the line with my other before filters I get the error: Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id I suspect it''s because in my confirm_owner I call @owner = Product.find(params[:id].to_i but the before filter hasn''t been passed any value for the product_id to find. Does that make sense? So maybe the before_filter isn''t the way to go? -Vince -- Posted via http://www.ruby-forum.com/.
Vince W. wrote:> What you are saying makes sense, and I''ve incorporated that into my > code: > > class PostController < ApplicationController > include AuthenticatedSystem > before_filter :login_required, > :find_user, > :confirm_owner, :only => [:edit] > > > but when I put the line with my other before filters I get the error: > > Called id for nil, which would mistakenly be 4 -- if you really wanted > the id of nil, use object_id > > I suspect it''s because in my confirm_owner I call > @owner = Product.find(params[:id].to_i > > but the before filter hasn''t been passed any value for the product_id to > find. Does that make sense? So maybe the before_filter isn''t the way > to go? > > -VinceI suspect its actually exploding on this line: unless @owner.user_id == @user.id Because you havent assigned anything to @user yet. -- Posted via http://www.ruby-forum.com/.
Alex Wayne wrote:> > I suspect its actually exploding on this line: > > unless @owner.user_id == @user.id > > Because you havent assigned anything to @user yet.I thought of that actually so I had added a definition for @ user in my confirm_user method: private def confirm_owner @user = User.find(session[:user].to_i) @owner = Product.find(params[:id].to_i) unless @owner.user_id == @user.id flash[:notice] = ''You are not the owner of this product.'' redirect_to :action => ''list'' end end Still have the same problem though. -- Posted via http://www.ruby-forum.com/.
Vince W. wrote:> Alex Wayne wrote: >> >> I suspect its actually exploding on this line: >> >> unless @owner.user_id == @user.id >> >> Because you havent assigned anything to @user yet. > > I thought of that actually so I had added a definition for @ user in my > confirm_user method: > > private > def confirm_owner > @user = User.find(session[:user].to_i) > @owner = Product.find(params[:id].to_i) > unless @owner.user_id == @user.id > flash[:notice] = ''You are not the owner of this product.'' > redirect_to :action => ''list'' > end > end > > > Still have the same problem though.Well there is only one spot your are calling the method "id" and that is on the @user object. Are you sure session[:user] has something in when you execute this? try this: def confirm_owner @user = User.find(session[:user]) @owner = Product.find(params[:id]) unless @user && @owner.user_id == @user.id flash[:notice] = ''You are not the owner of this product.'' redirect_to :action => ''list'' end end Since you can''t be the owner if you are not logged in, the unless statement first checks to see if @user is set. If @user is nil, the second condition does not need to be executed, and we do the redirect. If @user is a real user, we then check to see if that user is the owner. Also the to_i is not require for the find method, it''ll take a number as a string just fine. -- Posted via http://www.ruby-forum.com/.
Alex Wayne wrote:> > try this: > > def confirm_owner > @user = User.find(session[:user]) > @owner = Product.find(params[:id]) > unless @user && @owner.user_id == @user.id > flash[:notice] = ''You are not the owner of this product.'' > redirect_to :action => ''list'' > end > end >Same result... I''m pretty sure it''s getting nil b/c it''s not passing a product id -Vince -- Posted via http://www.ruby-forum.com/.
Vince W. wrote:> Alex Wayne wrote: > >> >> try this: >> >> def confirm_owner >> @user = User.find(session[:user]) >> @owner = Product.find(params[:id]) >> unless @user && @owner.user_id == @user.id >> flash[:notice] = ''You are not the owner of this product.'' >> redirect_to :action => ''list'' >> end >> end >> >Ok, I did some more hacking around on this. Turns out the nil error is because of the before_filter confirm_owner :only => [:edit] line when I remove the :only => [:edit] part I get an error saying Couldn''t find Product without an ID. I have no idea why I get a nil error when I try to use only or except in the before filter but regardless I think I''m going to have to cut/paste this code in a few different places because of product_id issue. -- Posted via http://www.ruby-forum.com/.
Vince W. wrote:> Vince W. wrote: >> Alex Wayne wrote: >> >>> >>> try this: >>> >>> def confirm_owner >>> @user = User.find(session[:user]) >>> @owner = Product.find(params[:id]) >>> unless @user && @owner.user_id == @user.id >>> flash[:notice] = ''You are not the owner of this product.'' >>> redirect_to :action => ''list'' >>> end >>> end >>> >> > > Ok, I did some more hacking around on this. Turns out the nil error is > because of the before_filter confirm_owner :only => [:edit] line > when I remove the :only => [:edit] part I get an error saying Couldn''t > find Product without an ID. > > I have no idea why I get a nil error when I try to use only or except in > the before filter but regardless I think I''m going to have to cut/paste > this code in a few different places because of product_id issue.params should be available in before_filters, try sticking the value of params[:id] in your session with "session[:debug] = params[:id]" and looking at its value on the error page. If its nil, then you are not successfully passing the value from the url into your action, and you may want to look at your routes. -- Posted via http://www.ruby-forum.com/.