Hi, i was wondering if there was a nice clean way(after all, it is ruby) to change the find method of a certain model/class (Page) so that if i wanted to use a find method on a @page instance it would return only specific rows from the table(if the page.published == true/false: the pages table looked like SQL: ... id int not null auto_increment, published tinyint(1) not null, something varchar not null, ... end of table and i had a query: @page = Page.find(:all) it would return only the pages that had pages.published == true. i thought the def would be something like: Class Page < ActiveRecord::Base def find super self.find(:all, :conditons => ''published=1'') end but it isn''t working. could possibly do def find_published self.find(:all, :conditons => ....) end and change all of my find methods to @page.find_published...? am i going down the wrong train of thought? where/how do i change a class method to my own needs without ruining the initial method...? ? thanks for any reference, harp -- Posted via http://www.ruby-forum.com/.
class Page ... def self.find(...) end end don''t call super as this will call ActiveRecord''s find only to call it again when you explicitly call it (in the next line) cheers -----Original Message----- From: rails-bounces@lists.rubyonrails.org [mailto:rails-bounces@lists.rubyonrails.org] On Behalf Of harper Sent: Wednesday, August 09, 2006 11:25 AM To: rails@lists.rubyonrails.org Subject: [Rails] changing find method Hi, i was wondering if there was a nice clean way(after all, it is ruby) to change the find method of a certain model/class (Page) so that if i wanted to use a find method on a @page instance it would return only specific rows from the table(if the page.published == true/false: the pages table looked like SQL: ... id int not null auto_increment, published tinyint(1) not null, something varchar not null, ... end of table and i had a query: @page = Page.find(:all) it would return only the pages that had pages.published == true. i thought the def would be something like: Class Page < ActiveRecord::Base def find super self.find(:all, :conditons => ''published=1'') end but it isn''t working. could possibly do def find_published self.find(:all, :conditons => ....) end and change all of my find methods to @page.find_published...? am i going down the wrong train of thought? where/how do i change a class method to my own needs without ruining the initial method...? ? thanks for any reference, harp -- Posted via http://www.ruby-forum.com/. _______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails
> don''t call super as this will call ActiveRecord''s find only to call it > again > when you explicitly call it (in the next line)(recursive loop?) ...ok. a little more detailed description of this issue: i want to define the find method for a Page model. if an admin is logged on to the site(i.e, @session[''admin'']!=nil)i want him to see all of the pages in the ''pages'' table, but if a regular user uses the application i only want him to see the pages that are defined with pages.publish = 1/true (discarding all of the rows that have publish=0/false). i suppose i could do this via going into every action displaying @pages = Page.find(:....:conditons => ''publish=1''..etc) but there are a couple good places i need to do this, and aside from it being more DRY, it is also a much more asthetic solution to do it via the model(it should be beautiful). ...but like many of the beautiful solutions, the way getting there is pretty ugly; i''ve tried taking the ''find'' source-code from activerecord and modifiying it, but truthfully enough, it hasn''t led anywhere important, aside from wasting me a great deal of time... def self.find(*args) records = [] options = extract_options_from_args!(args) validate_find_options(options) set_readonly_option!(options) case args.first when :first then records = find_initial(options) when :all then records = find_every(options) else records = find_from_ids(args, options) end records.each { |record| record.publish==1} records end ...is there a simpler way to do this? i even dug dipper and tried changing the ''find_initial'', ''find_every'', and ''find_from_ids'' methods, but then i realized i was running around in circles and not really getting anywhere substansial. any ideas? many thanks, harp -- Posted via http://www.ruby-forum.com/.
Sounds messy. Maybe you need to use with_scope<http://www.codyfauser.com/articles/2006/02/01/using-with_scope-to-refactor-messy-finders> . Hope that suffice -- choonkeat - http://blog.yanime.org/ - http://www.rssfwd.com/ On 8/10/06, harper <harper@chalice.cil> wrote:> > > don''t call super as this will call ActiveRecord''s find only to call it > > again > > when you explicitly call it (in the next line) > (recursive loop?) ...ok. > > a little more detailed description of this issue: > > i want to define the find method for a Page model. > if an admin is logged on to the site(i.e, @session[''admin'']!=nil)i want > him to see all of the pages in the ''pages'' table, but if a regular user > uses the application i only want him to see the pages that are defined > with pages.publish = 1/true (discarding all of the rows that have > publish=0/false). > > i suppose i could do this via going into every action displaying @pages > = Page.find(:....:conditons => ''publish=1''..etc) but there are a couple > good places i need to do this, and aside from it being more DRY, it is > also a much more asthetic solution to do it via the model(it should be > beautiful). > > ...but like many of the beautiful solutions, the way getting there is > pretty ugly; i''ve tried taking the ''find'' source-code from activerecord > and modifiying it, but truthfully enough, it hasn''t led anywhere > important, aside from wasting me a great deal of time... > > def self.find(*args) > records = [] > options = extract_options_from_args!(args) > validate_find_options(options) > set_readonly_option!(options) > case args.first > when :first then records = find_initial(options) > when :all then records = find_every(options) > else records = find_from_ids(args, options) > end > records.each { |record| record.publish==1} > records > end > > ...is there a simpler way to do this? i even dug dipper and tried > changing the ''find_initial'', ''find_every'', and ''find_from_ids'' methods, > but then i realized i was running around in circles and not really > getting anywhere substansial. > > any ideas? > many thanks, > > harp > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060810/acc7d86d/attachment.html
harper wrote:> and change all of my find methods to @page.find_published...? > am i going down the wrong train of thought? where/how do i change a > class method to my own needs without ruining the initial method...?def self.find(args) self.with_scope(:find => { :conditions => "published = 1" }) do super(args) end end Usual caveats for code written in an email and not tested apply :-) -- Josh Susser http://blog.hasmanythrough.com -- Posted via http://www.ruby-forum.com/.
is there any way to do this???? or am i just wasting my time?? -- Posted via http://www.ruby-forum.com/.
thanks!!! beautiful. i should get more into the whole "scope" issue...i have never really used it; and it seems important enough.. in much debt. thanks again, harp -- Posted via http://www.ruby-forum.com/.
in application_controller.rb def get_pages if session[:admin] @pages = Page.find :all else @pages = Page.find_all_by_publish(1) end end Then in your controllers before_filter :get_pages, :only =>[:list, :index, :some_other_action] def list # @pages should already be filled from before_filter so no need to do it here. end That should work for you I think... It''s a bad idea to do things like that in the model because they''re related to session... MVC likes separation of business rules from flow control. On 8/10/06, harper <harper@chalice.cil> wrote:> > is there any way to do this???? or am i just wasting my time?? > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060810/eaea18a7/attachment.html