给定integer
和uuid
主键的表是什么是集成多态连接(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
包括确保正确铸造发生的最佳方法是什么?
你能描述一下你的likes
表吗?我想它包含
user_id
为整数,likeable_id
为整数,likeable_type
为整数因此,从技术上讲,你无法在uuid
和id
两个字段的范围内创建与likeable_id
字符串和likeable_type
相同的多态关联作为整数。
作为解决方案 - 您可以简单地将id
添加为posts
表的主键而不是uuid
。如果您可能不想在URL中显示帖子的ID,或出于其他安全原因 - 您仍然可以像以前一样使用uuid
。
您可以定义自己的方法来检索likes
模型中的Interest
。
def likes
Like.where("likeable_type = ? AND likeable_id = ?::text", self.class.name, id)
end
这个解决方案的问题在于你没有定义关联,所以像'has_many through'这样的东西不起作用,你也必须自己定义这些方法/查询。
我对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