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

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

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

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 :slight_smile:


Josh S.
http://blog.hasmanythrough.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

is there any way to do this??? or am i just wasting my time??

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.

Sounds messy. Maybe you need to use
with_scopehttp://www.codyfauser.com/articles/2006/02/01/using-with_scope-to-refactor-messy-finders
.

Hope that suffice

choonkeat