保存时如何让我的模型使用我的缓存?

Dav*_*ave 6 caching model ruby-on-rails save ruby-on-rails-5

我正在使用Rails 5.我有以下型号

class MyObject < ActiveRecord::Base
    ...
  belongs_to :distance_unit

    ...
  def save_with_location
    transaction do
      address = LocationHelper.get_address(location) 
      if !self.address.nil? && !address.nil?
        self.address.update_attributes(address.attributes.except("id", "created_at", "updated_at")) 
      elsif !address.nil?
        address.race = self
        address.save
      end

      # Save the object
      save
    end 
  end
Run Code Online (Sandbox Code Playgroud)

通过一些狡猾的调试,我发现"save"方法会导致执行此查询...

  DistanceUnit Load (0.3ms)  SELECT  "distance_units".* FROM "distance_units" WHERE "distance_units"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  ? app/models/my_object.rb:54:in `block in save_with_location'
Run Code Online (Sandbox Code Playgroud)

每次调用上述方法时都会发生这种情况.这不是最佳的,因为我设置了我的DistanceUnit模型以获得缓存.下面是它的代码.如何让我的"保存"方法自动使用缓存而不是每次都执行此查询?

class DistanceUnit < ActiveRecord::Base

  def self.cached_find_by_id(id)
    Rails.cache.fetch("distanceunit-#{id}") do
      puts "looking for id: #{id}" 
      find_by_id(id)
    end
  end

  def self.cached_find_by_abbrev(abbrev)
    Rails.cache.fetch("distanceunit-#{abbrev}") do
      find_by_abbrev(abbrev)
    end
  end

  def self.cached_all()
    Rails.cache.fetch("distanceunit-all") do
      all
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

Sla*_*a.K 3

在此更改后, Rails 5belongs_to默认要求关联。这意味着关联记录在保存时必须存在于数据库中,否则验证将失败。有几种可能的方法可以解决您的问题

1)distance_unit在保存MyObject实例之前从缓存中手动设置,以防止从数据库中获取它:

  def save_with_location
      # ...

      # Save the object
      self.distance_unit = DistanceUnit.cached_find_by_id(self.distance_unit_id)
      save
    end 
  end
Run Code Online (Sandbox Code Playgroud)

2) 或选择退出此行为:

您可以传递optional: truebelongs_to协会,这将删除此验证检查:

class MyObject < ApplicationRecord
  # ...
  belongs_to :distance_unit, optional: true
  # ...
end
Run Code Online (Sandbox Code Playgroud)