Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot fetch_multi_by polymorphic field #392

Open
thallada opened this issue Sep 24, 2019 · 1 comment
Open

Cannot fetch_multi_by polymorphic field #392

thallada opened this issue Sep 24, 2019 · 1 comment

Comments

@thallada
Copy link

I have made a new rails app with these models on the latest master of identity_cache:

models/item.rb

class Item < ApplicationRecord
  include IdentityCache

  belongs_to :widget, polymorphic: true

  cache_belongs_to :widget
  cache_index :widget
end

models/foo_widget.rb

class FooWidget < ApplicationRecord
  include IdentityCache

  has_many :items, as: :widget

  cache_has_many :items, inverse: :widget
end

models/bar_widget.rb

class BarWidget < ApplicationRecord
  include IdentityCache

  has_many :items, as: :widget

  cache_has_many :items, inverse: :widget
end

schema:

class AddTables < ActiveRecord::Migration[5.2]
  def change
    create_table :items do |t|
      t.bigint :widget_id, null: false
      t.string :widget_type, null: false
    end

    create_table :foo_widgets

    create_table :bar_widgets

    add_index :items, %i[widget_type widget_id]
  end
end

I would like to be able to run this:

widgets = FooWidget.fetch_multi([1, 2, 3])
items = Item.fetch_multi_by_widget(widgets)

But, that generates an invalid SQL query:

ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: widget: SELECT widget, "items"."id" FROM "items" WHERE "items"."widget_type" = ? AND "items"."widget_id" IN (?, ?))

I can't change my cache_index to cache_index :widget_id, :widget_type because fetch_multi_by methods are only generated for cache_indexes with only one field.

I used to be able to pass in arrays into the fetch_by_widget_id_and_subject_type methods in 0.5.1, but now that doesn't work on master (e.g. an array of widget_ids generates a SQL query with NULL as the widget_id value). I guess was never the way those methods were intended to be used, but now I don't have a way to bulk fetch Items in a way that won't make N+1 queries when the cache is missed.

@dylanahsmith
Copy link
Contributor

I can't change my cache_index to cache_index :widget_id, :widget_type because fetch_multi_by methods are only generated for cache_indexes with only one field.

Right, there isn't cache_attribute by multiple columns support, which means there is no cache_index by multiple columns support.

In your example

widgets = FooWidget.fetch_multi([1, 2, 3])
items = Item.fetch_multi_by_widget(widgets)

it looks like you could add cache_has_many :items, embed: :ids to FooWidget, then you could do

widgets = FooWidget.fetch_multi([1, 2, 3], include: :items)
items = widgets.flat_map(&:items)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants