【问题标题】:What is the best way for caching database query for the Service Object inside the iterations?在迭代中缓存服务对象的数据库查询的最佳方法是什么?
【发布时间】:2019-06-08 13:47:35
【问题描述】:

我有一个 Rails 服务对象 - CarChecker 和模型 AvailableCar:

class CarChecker
  def car_is_available?(car)
    list_of_available_cars.include?(car)
  end

  def list_of_available_cars
    AvailableCar.all.map { ... }
  end
end

然后我检查控制器中某处的每辆车

cars.each do |car|
  CarChecker.new().car_is_available?(car)
end

如何避免每次迭代都发送请求 AvailableCar.all 并且只发送一次?缓存此类行为的最佳方法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby database activerecord


    【解决方案1】:

    您经常会看到分配给实例变量以进行缓存的方法。

    def list_of_available_cars
      @allcars ||= AvailableCar.all.map { ... }
    end
    

    第一次调用list_of_available_cars,将执行AvailableCars.all...,并将结果存储在实例变量中。之后的时间,存储的值将被返回。

    要让它以这种方式工作,您需要重用服务类的同一个实例。

    checker = CarChecker.new
    cars.each do |car|
      checker.car_is_available?(car)
    end
    

    如果您每次都必须使用CarChecker 的新实例,那么您可以使用类变量而不是实例变量(即使用@@ 而不是@):

    def list_of_available_cars
      @@allcars ||= AvailableCar.all.map { ... }
    end
    

    只要您的 AvailableCar.all.map { ... } 总是返回相同的结果,那应该没问题。

    【讨论】:

    • 不幸的是,它对我不起作用,因为我使用了更复杂的结构,并且我需要在每次迭代时将参数 car 发送到 CarChecker.new(car) 构造函数
    猜你喜欢
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 2011-03-20
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多