bli*_*183 14 scope ruby-on-rails ruby-on-rails-3
基于Rails 3 API,范围和类方法之间的差异几乎不存在.
class Shipment < ActiveRecord::Base
def self.unshipped
where(:shipped => false)
end
end
Run Code Online (Sandbox Code Playgroud)
是相同的
scope :unshipped, where(:shipped => false)
Run Code Online (Sandbox Code Playgroud)
但是,我发现我有时会使用它们得到不同的结果.
虽然它们都生成相同的,正确的SQL查询,但在调用时,范围似乎并不总是返回正确的值.看起来这个问题只发生在它在方法中两次调用相同的方式时,尽管是在不同的货件上.第二次调用时,使用范围时它会返回与第一次相同的操作.然而,如果我使用类方法,它可以正常工作.
使用范围时是否会出现某种查询缓存?
编辑:
order.line_items.unshipped
Run Code Online (Sandbox Code Playgroud)
上面的行是调用范围的方式.订单有很多line_items.
generate_multiple_shipments方法被调用两次,因为测试会创建一个订单并生成货件以查看其数量.然后它会对订单进行更改并重新生成货件.但是,group_by_ship_date返回与订单的第一次迭代相同的结果.
def generate_multiple_shipments(order)
line_items_by_date = group_by_ship_date(order.line_items.unshipped)
line_items_by_date.keys.sort.map do |date|
shipment = clone_from_order(order)
shipment.ship_date = date
line_items_by_date[date].each { |line_item| shipment.line_items << line_item }
shipment
end
end
def group_by_ship_date(line_items)
hash = {}
line_items.each do |line_item|
hash[line_item.ship_date] ||= []
hash[line_item.ship_date] << line_item
end
hash
end
Run Code Online (Sandbox Code Playgroud)
我认为你的调用不正确。你应该添加所谓的查询方法来执行作用域,例如all,,,,即:firstlast
order.line_items.unshipped.all
Run Code Online (Sandbox Code Playgroud)
我观察到一些不一致的情况,特别是在 rspec 中,通过添加查询方法可以避免这些不一致。
您没有发布测试代码,所以很难准确地说,但我的经验是,修改关联记录后,您必须强制重新加载,因为查询缓存并不总是足够智能来检测更改。通过传递true给关联,您可以强制关联重新加载并重新运行查询:
order.line_items(true).unshipped.all
Run Code Online (Sandbox Code Playgroud)