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)
。我想将其作为activerecord关联。
答案 0 :(得分:2)
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
...请参见docs
Sample.first.pictures.map(&:imageable)。我想将其作为activerecord关联。
...是我认为这是不可能的,但是您仍然可以将它们全部作为Array获得。原因是没有对应于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(...)