ruby-on-rails - 多态关联有很多关系
问题描述
class Sample
has_many :pictures
end
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
belongs_to :sample
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
获取给定样本的所有产品或员工的关联应该是什么。
Sample.first.pictures.map(&:imageable)
. 我想把它作为一个活动记录关联。
解决方案
解决方法:
class Sample
has_many :pictures
has_many :imageable_employees, through: :pictures, source: :imageable, source_type: 'Employee'
has_many :imageable_products, through: :pictures, source: :imageable, source_type: 'Product'
end
用法:
sample = Sample.first
employees = sample.imageable_employees
products = sample.imageable_products
...见文档
解释:
Sample.first.pictures.map(&:imageable)。我想把它作为一个活动记录关联。
......我认为这是不可能的,但你仍然可以将它们全部作为一个数组来代替。原因是没有对应于imageable
关联的表(模型),而是对应于 ANY 模型,这使 SQL 查询复杂化,因此我认为这是不可能的。
例如,考虑以下查询:
imageables_created_until_yesterday = Sample.first.something_that_returns_all_imageables.where('created_at < ?', Time.zone.now.beginning_of_day)
# what SQL from above should this generate? (without prior knowledge of what tables that the polymorphic association corresponds to)
# => SELECT "WHAT_TABLE".* FROM "WHAT_TABLE" WHERE (sample_id = 1 AND created_at < '2018-08-27 00:00:00.000000')
# furthermore, you'll notice that the SQL above only assumes one table, what if the polymorphic association can be at least two models / tables?
替代解决方案:
根据您的应用程序的需求和您尝试执行的“查询”,您可能会或可能不会考虑以下实现abstract_imageable
(真实表)模型以便您能够执行查询的模型。您还可以在此abstract_imageable
模型中添加更多您认为在所有“可成像”记录中“共享”的属性。
随意重命名abstract_imageable
class Sample
has_many :pictures
has_many :abstract_imageables, through: :pictures
end
class Picture
belongs_to :sample
has_many :abstract_imageables
end
# rails generate model abstract_imageable picture:belongs_to imageable:references{polymorphic}
class AbstractImageable
belongs_to :picture
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :abstract_imageables, as: :imageable
has_many :pictures, through: :abstract_imageables
end
class Product < ApplicationRecord
has_many :abstract_imageables, as: :imageable
has_many :pictures, through: :abstract_imageables
end
用法:
sample = Sample.first
abstract_imageables = sample.abstract_imageables
puts abstract_imageables.first.class
# => AbstractImageable
puts abstract_imageables.first.imageable.class
# => can be either nil, or Employee, or Product, or whatever model
puts abstract_imageables.second.imageable.class
# => can be either nil, or Employee, or Product, or whatever model
# your query here, which I assumed you were trying to do because you said you wanted an `ActiveRecord::Relation` object
abstract_imageables.where(...)
推荐阅读
- javascript - Java Script:当从输入类型 = 'color' 中选择颜色时,如何提取 HSL 值?
- rabbitmq - 在 RabbitMQ 路由键或标头的属性中使用否定
- javascript - 更新 MongoDB 中的填充数组 - 补丁请求被接受但不更新新项目
- jmeter - JMeter 记录 - “ERR_SSL_PROTOCOL_ERROR”和“软件导致连接中止:套接字写入错误”
- swift - 是否可以在多个 ViewController 中快速创建串行队列
- java - springboot中redis CacheManager中反序列化的错误处理
- reactjs - 使用 jsonPlaceHolder 和 react-admin 时出现 CORS 错误
- html - 我可以让 Swiper 响应式显示图像的高度相同吗
- java - Eclipse 上的按钮 ESC 表示问题
- c# - Unity:ARRaycastManager.Raycast 是否仅适用于触摸输入?