rails 5 API low-level caching

Deadly 提交于 2019-12-11 06:21:09

问题


I am a bit confused regarding Rails API caching. I am using JSONAPI spec and fast_jsonapi gem and trying to cache the vehicle itself on show action and if there are params coming over like include=service_notes,service_alerts then I would like to cache those too. This is my initial approach but not sure if it is right.

I have 2 main issues:

  1. For the vehicle caching itself is there a better approach than my vehicle = Vehicle.find_cached(params[:id]). This is not using updated_at but an after save callback to update the cache if vehicle has been updated. I just don't see if I could somehow use sth like Rails.cache.fetch(["vehicles", vehicle], version: vehicle.updated_at) as it is proposed here: https://github.com/rails/rails/pull/29092 since this needs the vehicle instance. As you see the set_vehicle controller method is pretty awkward.

  2. Does this Rails.cache.fetch(['vehicles', vehicle, include_params], version: vehicle.updated_at) make any sense? I am trying to cache the query based on the different include params. Maybe it is overkill and I could just include everything and cache it that way like:

    Rails.cache.fetch(['vehicles', vehicle, 'with_includes'], version: vehicle.updated_at) do Vehicle.includes(:vehicle_alerts, :service_notes, :service_intervals).find(params[:id]) end

What is the correct way to handle caching here?

service_note.rb setup same for service_interval.rb and vehicle_alert.rb

class ServiceNote < ApplicationRecord
  belongs_to :vehicle, touch: true
end

vehicle.rb

class Vehicle < ApplicationRecord
  after_save :update_cache
  has_many :vehicle_alerts, dependent: :delete_all
  has_many :service_notes, dependent: :delete_all
  has_many :service_intervals, dependent: :delete_all

  def update_cache
    Rails.cache.write(['vehicles', vehicle_id], self)
  end

  def self.find_cached(vehicle_id)
    Rails.cache.fetch(['vehicles', vehicle_id]) { find(vehicle_id) }
  end
end

vehicles_controller.rb

before_action :set_vehicle, only: [:show]

def show
  render json: VehicleSerializer.new(@vehicle, options).serialized_json
end

private

def set_vehicle
  vehicle = Vehicle.find_cached(params[:id])

  @vehicle = Rails.cache.fetch(['vehicles', vehicle, include_params], version: vehicle.updated_at) do
    Vehicle.includes(include_params).find(params[:id])
  end

  authorize @vehicle
end

vehicle_serializer.rb (with fast_jsonapi gem)

# same for :service_notes and :vehicle_alerts
has_many :service_intervals do |vehicle, params|
  if params[:include] && params[:include].include?(:service_intervals)
    vehicle.service_intervals
  end
end

来源:https://stackoverflow.com/questions/51689938/rails-5-api-low-level-caching

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!