(Nuby to Ruby and Rails...) I''ve implemented security using the login generator in a simple app so that I have a user table, a roles table, and a join between them (roles_users). All works as expected. I now need to check if a user has a specific role, but my approach is off somehow. Here''s what I''ve tried thusfar: user_roles = @session[:user].roles user_roles.find { |r| r.name == "officer"} When this executes, I get "can''t locate Role without ID...". What I *thought* I was doing was searching an array (user_roles) for a value, but this seems to imply that I''ve doing a db search. What am I missing here? Is there a better way to approach this? (I''ve checked, and user_roles does hold the correct list of objects...) TIA, Keith
Julian ''Julik'' Tarkhanov
2005-Oct-12 04:10 UTC
Re: Searching an attribute in a hmabtm relationship
On 12-okt-2005, at 0:12, Keith Lancaster wrote:> (Nuby to Ruby and Rails...) > I''ve implemented security using the login generator in a simple app so > that I have a user table, a roles table, and a join between them > (roles_users). All works as expected. I now need to check if a user > has a specific role, but my approach is off somehow. > > Here''s what I''ve tried thusfar: > > user_roles = @session[:user].roles > user_roles.find { |r| r.name == "officer"} > > When this executes, I get "can''t locate Role without ID...". What I > *thought* I was doing was searching an array (user_roles) for a value, > but this seems to imply that I''ve doing a db search. What am I missing > here? Is there a better way to approach this? (I''ve checked, and > user_roles does hold the correct list of objects...)find in this case is overridden and hooked into AR''s find. What you need I assume is this: allow_access if @session[:user].roles.include?(Role.find_by_name ("officer")) -- Julian "Julik" Tarkhanov
Ezra Zygmuntowicz
2005-Oct-12 04:55 UTC
Re: Searching an attribute in a hmabtm relationship
On Oct 11, 2005, at 9:10 PM, Julian ''Julik'' Tarkhanov wrote:> > On 12-okt-2005, at 0:12, Keith Lancaster wrote: > > >> (Nuby to Ruby and Rails...) >> I''ve implemented security using the login generator in a simple >> app so >> that I have a user table, a roles table, and a join between them >> (roles_users). All works as expected. I now need to check if a user >> has a specific role, but my approach is off somehow. >> >> Here''s what I''ve tried thusfar: >> >> user_roles = @session[:user].roles >> user_roles.find { |r| r.name == "officer"} >> >> When this executes, I get "can''t locate Role without ID...". What I >> *thought* I was doing was searching an array (user_roles) for a >> value, >> but this seems to imply that I''ve doing a db search. What am I >> missing >> here? Is there a better way to approach this? (I''ve checked, and >> user_roles does hold the correct list of objects...) >> > > find in this case is overridden and hooked into AR''s find. > > What you need I assume is this: > > allow_access if @session[:user].roles.include?(Role.find_by_name > ("officer")) > > -- > Julian "Julik" Tarkhanov > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > >Or you can do it like this to make sure it uses the array version of find and not the AR one:>> user_roles.to_a.find { |r| r.name == "officer"}HTH- -Ezra Zygmuntowicz WebMaster Yakima Herald-Republic Newspaper ezra-gdxLOakOTQ9oetBuM9ipNAC/G2K4zDHf@public.gmane.org 509-577-7732
Ezra Zygmuntowicz <ezra@...> writes:> > > On Oct 11, 2005, at 9:10 PM, Julian ''Julik'' Tarkhanov wrote:> > > > find in this case is overridden and hooked into AR''s find. > > > > What you need I assume is this: > > > > allow_access if <at> session[:user].roles.include?(Role.find_by_name > > ("officer")) > >I''m certain you are right, but I''m not certain why :-). Being new to ruby, perhaps I''m not understanding an aspect of containers or inheritance in ruby. Are you saying that the find method in the role object, which is contained in the array, is overriding the find method in the array? IOW, does a method in the contained class override a method in the container? Keith
Ezra Zygmuntowicz
2005-Oct-12 22:02 UTC
Re: Re: Searching an attribute in a hmabtm relationship
On Oct 12, 2005, at 6:34 AM, Keith wrote:> Ezra Zygmuntowicz <ezra@...> writes: > > >> >> >> On Oct 11, 2005, at 9:10 PM, Julian ''Julik'' Tarkhanov wrote: >> > > >>> >>> find in this case is overridden and hooked into AR''s find. >>> >>> What you need I assume is this: >>> >>> allow_access if <at> session[:user].roles.include? >>> (Role.find_by_name >>> ("officer")) >>> >>> > > I''m certain you are right, but I''m not certain why :-). Being new > to ruby, > perhaps I''m not understanding an aspect of containers or > inheritance in ruby. > Are you saying that the find method in the role object, which is > contained in > the array, is overriding the find method in the array? IOW, does a > method in the > contained class override a method in the container? > > Keith > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > >Well ActiveRecord collections have their own find method that finds stuff from the database. So the :conditions string gets turned into the where clause in an SQL statement. Like this:>> user_roles.find :all, :conditions => "role = officer"But the standard Array class has a find method that takes a block and returns the elements of the array that return true when evaluated in the block. So if you cast your AR collection with a .to_a (to array) method you don;t loose any info but when you call the .find method after the cast it uses the find method that it looks up in the Array class. Whereas Active Record defines its own find method that works with the database. You use the to_a method to make sure that the Array#find method is used and not the ActiveRecord#find method. Note that the user_roles collection must be pre populated from the db already:>> user_roles.to_a.find { |r| r.name == "officer"}Active record collections behave like Array collections except they are populated from the db and the find method is different from a standard array. HTH- -Ezra Zygmuntowicz Yakima Herald-Republic WebMaster http://yakimaherald.com 509-577-7732 ezra-gdxLOakOTQ9oetBuM9ipNAC/G2K4zDHf@public.gmane.org