【问题标题】:STI polymorphic has_many uses wrong type valueSTI 多态 has_many 使用错误的类型值
【发布时间】:2019-07-01 12:03:57
【问题描述】:

我有以下 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。

【问题讨论】:

    标签: ruby-on-rails polymorphic-associations


    【解决方案1】:

    来自 Rails 文档:

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

    注意: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,您可以在Product 表中添加type 列。但这完全取决于您对OneProduct 模型的需求,如果该模型上的default_scope 可以使其在不添加type 列的情况下为您工作,那么不要将它添加到Product 表中,如果这不起作用然后您可以添加列,然后在查询OneProduct 模型时添加default_scope 以获取products.type = OneProduct

    【讨论】:

    • 感谢您的信息。说得通。我已经在Product b/c 上有一个type 列,该表启用了STI。所以添加一个默认范围应该可以解决我的需求
    猜你喜欢
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多