定义一个方法来捕获类中的a_method []

时间:2011-08-31 14:59:12

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord

我有很多这样的话:

User.active[0..5]

打电话:

class User
  def active
     (an ActiveRelation)
  end
end

出于性能原因,我试图做这样的事情:

class User
  def active[limit]
     (an ActiveRelation).limit(limit.to_a.size)
  end
end

不幸的是它没有用,有任何想法来实现这个吗?

==编辑

更清洁:

class RelationWithLimit < ActiveRecord::Relation
  def [] selector
    case selector
    when Integer
      self.offset(selector).limit(1)
    when Range
      self.offset(selector.to_a[0]).limit(selector.to_a.size)
    end
  end
end

class ActiveRecord::Base
  private 
    def self.relation #:nodoc:
      @relation ||= RelationWithLimit.new(self, arel_table)
      finder_needs_type_condition? ? @relation.where(type_condition) : @relation
    end
end

4 个答案:

答案 0 :(得分:4)

您可以拥有自己的ActiveRelation特殊子类

class UserReturnRelation < ActiveRecord::Relation
  def [] lim
    self.limit lim
  end
end

class User
  def active
     # Without knowing exactly what relation you are using
     # One way to instantiate the UserReturnRelation for just this call
     UserReturnRelation.new(self, arel_table).where("state = active")
  end
end

然后User.active [5]应该按预期工作。

编辑:添加了实例化信息。您可能需要查看Base#scopedBase#relation以获取更多信息

答案 1 :(得分:1)

你可以尝试使用params而不是array-indices吗?例如:

class User
  def active(the_limit)
     (an ActiveRelation).limit(the_limit)
  end
end
User.active(5)

(注意:未在任何实际的ActiveRelations上测试过......)

答案 2 :(得分:1)

你可以这样做:

class User
  def active
    Limiter.new((an ActiveRelation))
  end

  class Limiter
    def initialize(relation)
      @relation = relation
    end

    def method_missing(method, *arguments, &block)
      @relation.send(method, *arguments, &block)
    end

    def respond_to?(method, include_private = false)
      @relation.respond_to?(method, include_private) || super
    end

    def [](value)
      offset = value.to_a.first
      limit = value.to_a.last - offset
      @relation.offset(offset).limit(limit)
    end
  end
end

答案 3 :(得分:0)

好吧,你是在错误的类中定义方法。 User.active[0..5]调用active中的类方法User以及[]返回的任何类中的方法User.active,我假设它正在返回用户数组,Array已定义方法[],因此无需担心。

你可能会感到困惑,认为括号是某种用于将参数传递给函数的括号,而它们并非如此。试试这个:

class User
  class << self
    def [](values)
      self.find(values)
    end
  end
end

所以,如果你想使用带有id数组的find,你可以使用User[1,2,3]