ruby-on-rails - Rails 5.2 多态关联与多态条件
问题描述
楷模:
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)
返回一个预先加载的列表 AR 关系。
但是,我需要按 user_id 过滤,所以我尝试了...
Listing.includes(:listable).where(user_id: 100)
但我得到一个错误..
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column listings.user_id 不存在) LINE 1: SELECT "listings".* FROM "listings" WHERE "listings"."user_...
因为它似乎在列表中查找 user_id。但是,我需要在 listables 表上进行过滤,这意味着 Car 或 Truck 表。但是 listable 是定义的。
我也试过:
Listing.includes(listable:[:user]).where('users.id = 100')
但我得到...
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: missing FROM-clause entry for table "users") LINE 1: SELECT "listings".* FROM "listings" WHERE (users.id = 100) ... ^ : SELECT "listings".* FROM "listings" WHERE (users.id = 100) 限制 $1
更新:
然后试了
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)
但得到..
ActiveRecord::ConfigurationError(无法将“Car”加入名为“listable”的关联;也许您拼错了?)
因此,在上述工作正常之前,我无法尝试以下操作。
Listing.includes(:car, :truck).where(cars: { user_id: 1 }).or(Listing.includes(:car, :truck).where(trucks: { user_id: 1 }))
但是,我可以做 Listing.includes(:listable) 并且它确实有效,当我添加条件时它会中断。
解决方案
这是一个非常有趣的问题,我问了几个月。然后我找到了解决方案。
在您的Listing
模型中,为了能够包含您的polymorphic
模型,您需要告诉您的模型它们是相关的。
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(:listable).where(listings: { listable_type: Car.to_s }) }, foreign_key: :listable_id
belongs_to :truck, -> { includes(:listable).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 }))
推荐阅读
- python - 在创建文件并将文件推送到 SFTP 服务器时,不清楚 Pysftp 或 Dropox 是否滞后?
- android - Issue with unsigned apk installation in some devices, "App Not Installed" error
- amazon-web-services - 在 aws lambda 无服务器框架中使用自定义 vpc 而不是默认 vpc
- python - 如何在 python3.6 docker 镜像中安装 ibm_db_dbi 模块?
- kotlin - How to pass Generic Interface T to function with class reference as parameter
- redis - 如何降低epoll_wait调用的finish_task_switch()的CPU使用率?
- android - Android ConstraintLayout-2.0.0-alpha4 Fragment 与父级不匹配
- python - Python 3.6.5_1 安装在不正确的位置 (Mac OS)
- symfony - 删除时未定义的索引“用户”
- xcode - Xcode IDE 未使用运行脚本在目录中显示下载文件