UUID和整数字段上的多态关联

问题描述 投票:15回答:3

给定integeruuid主键的表是什么是集成多态连接(has_many)的最佳方法?例如:

class Interest < ActiveRecord::Base
  # id is an integer
  has_many :likes, as: :likeable
end

class Post < ActiveRecord::Base
  # id is a UUID
  has_many :likes, as: :likeable
end

class User < ActiveRecord::Base
  has_many :likes
  has_many :posts, through: :likes, source: :likeable, source_type: "Post"
  has_many :interests, through: :likes, source: :likeable, source_type: "Interest"
end

class Like < ActiveRecord::Base
  # likeable_id and likeable_type are strings
  belongs_to :likeable, polymorphic: true
  belongs_to :user
end

许多查询都有效:

interest.likes
post.likes
user.likes

然而:

user.interests

得到:

PG :: UndefinedFunction:ERROR:运算符不存在:integer =字符变化LINE 1:...兴趣“INNER JOIN”喜欢“ON”兴趣“。”id“=”喜欢“.... ^提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。:SELECT“interests”。* FROM“interests”INNER JOIN“likes”ON“interest”。“id”=“likes”。“ likeable_id“WHERE”喜欢“。”user_id“= $ 1 AND”喜欢“。”likeable_type“= $ 2

包括确保正确铸造发生的最佳方法是什么?

ruby-on-rails postgresql
3个回答
0
投票

你能描述一下你的likes表吗?我想它包含

  • user_id为整数,
  • likeable_id为整数,
  • likeable_type为整数
  • 任何第三方的领域

因此,从技术上讲,你无法在uuidid两个字段的范围内创建与likeable_id字符串和likeable_type相同的多态关联作为整数。

作为解决方案 - 您可以简单地将id添加为posts表的主键而不是uuid。如果您可能不想在URL中显示帖子的ID,或出于其他安全原因 - 您仍然可以像以前一样使用uuid


0
投票

您可以定义自己的方法来检索likes模型中的Interest

def likes
  Like.where("likeable_type = ? AND likeable_id = ?::text", self.class.name, id)
end

这个解决方案的问题在于你没有定义关联,所以像'has_many through'这样的东西不起作用,你也必须自己定义这些方法/查询。


-4
投票

我对ActiveRecord并不擅长,这绝对不是你想要的答案,但如果你需要一个临时*丑陋的解决方法,直到找到解决方案,你可以覆盖getter:

class User
  def interests
    self.likes.select{|like| like.likeable._type == 'Interest'}.map(&:likeable)
  end
end

*非常难看,因为它会加载所有用户喜欢然后对它们进行排序

编辑我发现this interesting article

self.likes.inject([]) do |result, like|
  result << like.likeable if like.likeable._type = 'Interest'
  result
end
© www.soinside.com 2019 - 2024. All rights reserved.