Hi guys, what do you think about this implementation (before I go off
and actually make it work).  The plan is to make it easier to write
extensions or plugins for find, as well as define your own options for
the precious first-level argument, :first, :all, etc.

If you want to skip to the paste/diff, it's here: http://pastie.caboo.se/89252

The current way:

      def find(*args)
        options = args.extract_options!
        validate_find_options(options)
        set_readonly_option!(options)

        case args.first
          when :first then find_initial(options)
          when :all   then find_every(options)
          else             find_from_ids(args, options)
        end
      end


A new way?

      def find(*args)
        options = args.extract_options!
        validate_find_options(options)
        set_readonly_option!(options)

        finder.dispatch(args, options)
      end


      # The Finder class allows you to easily define your own custom
find implementations.
      # Simply define this class in your model, and any of its methods
will be available
      # to your #find call as the first symbol.  For example,
      #
      #   User.find(:last, :conditions => ['name = ?', 'John'])
      #
      # is implemented as
      #
      #   class User < ActiveRecord::Base
      #     class Finder
      #       def last(options)
      #         @base.find(:first, options.update(:order => 'id desc'))
      #       end
      #     end
      #   end
      #
      #
      # Note: if you want to refer to any methods on Base other than
find, you'll need to
      # use the @base proxy object
      #
      #   def last(options)
      #     @base.find_by_sql(...)
      #   end
      #
      class Finder
        def initialize(base_instance)
          @base = base_instance
        end

        def dispatch(args, options)
          finder_method = args.first
          if finder_method.is_a?(Symbol) and respond_to?(finder_method)
            send(finder_method, options)
          else
            from_ids(args, options)
          end
        end

        def find(*args)
          @base.find(*args)
        end

        def all(options)
          @base.send(:find_every, options)
        end

        def first(options)
          @base.send(:find_initial, options)
        end

        def from_ids(ids, options)
          @base.send(:find_from_ids, ids, options)
        end

      end

      def finder
        @finder ||= Finder.new(self)
      end

...

This will also allow some fun things, like, keeping state in the
finder, or even recording the last SQL statistics.

  @user = User.find(2)
  User::Finder.records_returned => 25
  User::Finder.benchmark => 0.025

What do you guys think? All the AR tests still pass with this method,
since it's a fairly simple proxy, but it allows for much greater
customization.


Courtenay

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to