我不明白这种方法在这种情况下是如何工作的:
def self.page(page)
limit(default).offset(page * default).extending do
def per(num)
limit(num).offset(page * num)
end
end
与the original code略有不同。
我们可以使用ModelName.page(1).per(5)
。关于它是如何工作的我真的很困惑。看起来有些神奇的事情发生了。
答案 0 :(得分:2)
正如extending所说 -
用于通过其他方法扩展范围,通过模块或通过提供的块。返回的对象是一个关系,可以进一步扩展。
这是一个用于说明此功能的小例子:
Spree::Order.class_eval do
def self.scope_cart
self.where(currency: "INR").extending do
def orders_in_cart
where.not(state: 'cart')
end
end
end
end
Spree::Order.scope_cart.count # => 367
# SQl code
# SELECT COUNT(*) FROM "spree_orders" WHERE "spree_orders"."currency" = 'INR'
Spree::Order.count # => 367
到目前为止,您可以看到scope_cart
正在向我提供数据计数,这是self.where(currency: "INR")
的结果。那么,现在让我们看看orders_in_cart
给我们的新方法。
Spree::Order.scope_cart.orders_in_cart.count # => 342
# SQL code
# SELECT COUNT(*) FROM "spree_orders" WHERE "spree_orders"."currency" = 'INR' AND ("spree_orders"."state" != 'cart')
注意:请注意 SQL 代码,针对2种不同的情况。你的问题的答案就是答案。
现在再次来到你的榜样。当您致电ModelName.page(1)
时,您将获得此limit(default).offset(page * default)
的结果。现在,如果您需要额外的过滤,则会将per
方法称为ModelName.page(1).per(5)
,然后您将获得limit(num).offset(page * num)
的结果,该结果已应用 limit(default).offset(page * default)
。
进一步扩展它:
执行ModelName.page(1)
时,limit
每个值采用默认,offset
为1 * default
。等效的 SQL 是 -
SELECT "model_names".* FROM "model_names" LIMIT 20 OFFSET 20
执行ModelName.page(1).per(5)
时,limit
按5
取值,offset
为1 * 5
。等效的SQL是 -
SELECT "model_names".* FROM "model_names" LIMIT 5 OFFSET 5
在Rails中,我在documentation中看到如果你写的是User.limit(10).limit(20)
,它会生成SQL LIMIT 20
,意味着它需要最后 {{1链中的子句。 limit
的{{1}}也相同。
查看控制台生成的 SQL 代码:
true