STI多态has_many使用错误的类型值

时间:2019-07-01 12:03:57

标签: ruby-on-rails polymorphic-associations

我有以下STI模型,它们具有多态关联,其查询构造错误

class Product < ApplicationRecord
  has_many :images, as: :imageable
end

class OneProduct < Product
end

class Image < ApplicationRecord
  belongs_to :imageable
end

在Rails控制台中,当我这样做

> OneProduct.last.icon_images

触发的查询是

SELECT  * FROM images WHERE imageable_id = id AND imageable_type = 'Product'

我期望:

SELECT * from images WHERE imageable_id = id AND imageable_type = 'OneProduct'

我期望有什么问题吗?

边信息:数据库是postgres。

1 个答案:

答案 0 :(得分:1)

从Rails文档:

  

结合使用多态关联和单表继承(STI)有点棘手。为了使关联按预期工作,请确保将STI模型的基础模型存储在多态关联的type列中。继续上面的资产示例,假设有客人帖子和会员帖子使用STI的posts表。在这种情况下,posts表中必须有一个type列。

     

注意:在分配一个attachable_type= method时   可附加的。可连接项的class_name作为String传递。

class Asset < ActiveRecord::Base   
  belongs_to :attachable, polymorphic: true

  def attachable_type=(class_name)
     super(class_name.constantize.base_class.to_s)   
  end 
end

class Post < ActiveRecord::Base   
  # because we store "Post" in attachable_type now dependent: :destroy will work   
  has_many :assets,as: :attachable, dependent: :destroy 
end

class GuestPost < Post end

class MemberPost < Post end

来源: https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations

因此,它表示不需要存储imageable_type = OneProduct,而仅将其存储为Product,并且可以在type表中添加Product列。但这完全取决于您对OneProduct模型的需求,如果该模型上的default_scope可以在不添加type列的情况下为您工作,那么请不要将其添加到Product表,如果不起作用,则可以添加列,然后添加default_scope以在products.type = OneProduct模型上进行查询时获取OneProduct