Skip to content

[Question] How do you usually handle deeply nested objects cache invalidation? #140

@TheGr8OK

Description

@TheGr8OK

Thank you for maintaining this gem!

I have a nested object that I need it to invalidate the caching object when it is updated, and touch: true doesn't seem to do the trick here (see example below).

Models

# app/models/user.rb
class User < ApplicationRecord
  has_many :orders
end

# app/models/order.rb  
class Order < ApplicationRecord
  belongs_to :user
  has_many :order_items
  has_one :active_order_item, -> { where(active: true) }, class_name: 'OrderItem'

  def current_product
    order_items.order(:created_at).last.product
  end
end

# app/models/order_item.rb
class OrderItem < ApplicationRecord
  belongs_to :user
  belongs_to :order, touch: true  # This should invalidate order cache
  belongs_to :product
end

# app/models/product.rb
class Product < ApplicationRecord
  has_many :order_items
  enum :category, { digital: 0, physical: 1, service: 2 }
end

Graphql types

# app/graphql/types/user_type.rb
module Types
  class UserType < BaseObject
    
    field :order, Types::OrderType, null: false, cache_fragment: true
    def order
      object.orders.order(:created_at).last
    end
  end
end

# app/graphql/types/order_type.rb
module Types
  class OrderType < BaseObject
    field :status, String, null: false
    
    field :delivery_method, String, null: true
    def delivery_method
      # This field depends on nested product.category
      case object.current_product.category
      when 'digital'
        'email'
      when 'physical' 
        'shipping'
      when 'service'
        'appointment'
      end
    end
  end
end

When a product category is changed, the cache is not invalidated, even with touch: true on the association, the Order's updated_at doesn't get updated because the relationship is indirect (through OrderItem).

Also I have similar structures in my application. I was previously using https://github.com/stackshareio/graphql-cache and it worked fine with cache: true option, but I had to migrate after upgrading ruby/rails versions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions