Dim-
If I were you I would not try to over-ride AR::Base.find like that
You should just make your own method: find_with_scope. Then in that
method you can add your scope to the :conditions and then sedn it
along its way to AR::Base.find. then you wont have any problems with
find calling itself recursively or other code or plugins trying to
override find and making your code explode.
In my new plugin that deals with building the :conditions hash with
pure ruby like syntax, I wanted to override find but found it much
better to make my own ez_find that did what it needed to do and then
called AR::Base.find with the new :conditions. Here is my code for
that, you could adopt something similar and put it in a plugin so you
caoul d use it in your other apps as well.:
module EZ
#
# EZ::Condition plugin for generating the :conditions where clause
# for ActiveRecord::Base.find. And an extension to
ActiveRecord::Base
# called AR::Base.find_with_conditions that takes a block and
builds
# the where clause dynamically for you.
#
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
# The block recieves the condition for the model itself, as
well as for any :include associated model:
# Model.ez_find( :all, :include => [:comments, :readers]) do |
model, attachment, reader|
# model.title =~ ‘%article%’
# attachment.type = ‘image/png’
# reader.id = 2
# end
def ez_find(what, *args, &block)
options = args.last.is_a?(Hash) ? args.last : {}
options[:include] ||= []; options[:include] = [options
[:include]] if options[:include].kind_of?(Symbol)
outer_mapping = options.delete(:outer) || {} # preset :outer
value for each :include subcondition, defaults to :and
outer_mapping.default = :and
inner_mapping = options.delete(:inner) || {} # preset :inner
value for each :include subcondition, defaults to :and
inner_mapping.default = :and
if block_given?
klass = self.name.downcase.to_sym
conditions = [ez_condition(:outer => outer_mapping
[klass], :inner => inner_mapping[klass])] # conditions on self first
options[:include].uniq.each do |assoc|
conditions << reflect_on_association
(assoc).klass.ez_condition(:outer => outer_mapping[assoc], :inner =>
inner_mapping[assoc])
end
yield *conditions
condition = Caboose::EZ::Condition.new
conditions.each { |c| condition << c }
options[:conditions] = condition.to_sql
# p options[:conditions] if $DEBUG
end
self.find(what, options)
end
alias :find_with_conditions :ez_find
end # EZ module
and then:
ActiveRecord::Base.send :include, EZ #to include the code into rails.
See that last line? self.find(what, options)? Thats the call to
AR::Base.find, it just uses all the other trickery i do to build the
:conditions and send it to find. You can get the source of my plugin
here:
http://opensvn.csie.org/ezra/rails/plugins/dev/ez_where/
I would recommend you stay away from aliasing or overiding
AR::Base.find and make your own method, it will save you many headaches.
Cheers-
-Ezra
On Feb 2, 2006, at 1:15 AM, Dimitrij Denissenko wrote:
def self.find(*args)
class SomeObject < MyRecord
done it similarly to the ‘acts_as_paranoid’ extension using
aliasing, but it’s rather a hack than clean coding).
Thanks once again,
Dim
Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails
-Ezra Z.
Yakima Herald-Republic
WebMaster
509-577-7732
[email protected]