我有很多这样的话:
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
答案 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#scoped和Base#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]
。