class Car < ApplicationRecord
belongs_to :user
has_one :listing, as: :listable
has_one :firm, as: :firmable
has_one :seller, as: :sellable
end
class Truck < ApplicationRecord
belongs_to :user
has_one :listing, as: :listable
has_one :firm, as: :firmable
has_one :seller, as: :sellable
end
class Listing < ApplicationRecord
belongs_to :listable, polymorphic: true
has_many :favorites, dependent: :destroy
has_many :users_who_favorited, through: :favorites, source: :user
end
そして、Car と Truck の両方に user_id フィールドがあると仮定します。
Listing.includes(:listable) は、eargerloaded リストの AR 関係を返します。
ただし、user_idでフィルタリングする必要があるので、試してみました…
Listing.includes(:listable).where(user_id: 100)
しかし、エラーが発生します..
リストで user_id を検索しているようです。ただし、listables テーブルでフィルターする必要があるため、Car テーブルまたは Truck テーブルのいずれかを意味します。ただし、listable は定義されています。
私も試してみました:
Listing.includes(listable:[:user]).where(‘users.id = 100’)
でも分かりました…
それから試してみました
class Listing < ApplicationRecord
belongs_to :listable, polymorphic: true
has_many :favorites, dependent: :destroy
has_many :users_who_favorited, through: :favorites, source: :user
belongs_to :car, -> { includes(:listable).where(listable: { listable_type: Car.to_s }) }, foreign_key: :listable_id
belongs_to :truck, -> { includes(:listable).where(listable: { listable_type: Truck.to_s }) }, foreign_key: :listable_id
end
Listing.includes(:car, :truck) を試しましたが、得られました。
したがって、上記が機能するまで、以下を試すことはできません。
Listing.includes(:car, :truck).where(cars: { user_id: 1 }).or(Listing.includes(:car, :truck).where(trucks: { user_id: 1 }))
ただし、Listing.includes(:listable) を実行すると機能しますが、条件を追加すると壊れます。
これは私が数か月間抱いていた非常に興味深い質問です。それから私はそれに対する解決策を見つけました。
Listing モデルにポリモーフィック モデルを含めることができるようにするには、それらが関連していることをモデルに伝える必要があります。
class Car < ApplicationRecord
belongs_to :user
has_one :listing, as: :listable
has_one :firm, as: :firmable
has_one :seller, as: :sellable
end
class Truck < ApplicationRecord
belongs_to :user
has_one :listing, as: :listable
has_one :firm, as: :firmable
has_one :seller, as: :sellable
end
class Listing < ApplicationRecord
belongs_to :listable, polymorphic: true
has_many :favorites, dependent: :destroy
has_many :users, through: :favorites
#magic happens here
belongs_to :car, -> { includes(:listings).where(listings: { listable_type: Car.to_s }) }, foreign_key: :listable_id
belongs_to :truck, -> { includes(:listings).where(listings: { listable_type: Truck.to_s }) }, foreign_key: :listable_id
end
これで、単純に Listing.includes(:car, :truck) を行うことができ、完全に動作します :-)
あなたの場合:
Listing.includes(:car, :truck).where(cars: { user_id: 1 }).or(Listing.includes(:car, :truck).where(trucks: { user_id: 1 }))