我有5个表,likeable
都是user
,而likes
表记录了这个。
问题是5个表中的一个使用uuid
而不是主键的整数。所以我不能有一个典型的likeable_id
& likeable_type
是否可以设置处理不同主键类型的多态关联?
提前致谢
答案 0 :(得分:0)
我没有你的表名,但这是一个连接表的例子
class CreateJoins < ActiveRecord::Migration
def change
create_table :joins do |t|
t.belongs_to :uuid_id_model, type: :uuid # you specify the type
t.belongs_to :integer_id_model # you don't need anything
t.index %i[uuid_id_model integer_id_model], unique: true
t.timestamps
end
end
end
换句话说,在列上指定它们的类型uuid
如果您需要更改联接表的列类型,可以这样做:
class ChangeColumnType < ActiveRecord::Migration
def change
change_column :some_join_table, :some_join_column, :uuid
end
end
答案 1 :(得分:0)
我最终得到的解决方案是添加likeable_id_string
来存储任何uuid
主键。然后我覆盖getter和setter来执行以下操作:
# Overriding getters and setters to handle multiple primary key types on
# this polymorphic association ( String and Integer )
# Setters
def likeable=(value)
if !value.nil? && value.id.is_a?(String)
self[:likeable_id] = nil
self[:likeable_id_string] = value.id
self[:likeable_type] = value.class.name
else
self[:likeable_id_string] = nil
super(value)
end
end
# in case likeable_type and likeable_id are updated seperately. I believe
# this is done in FE (rather than passing an object to .likeable)
def likeable_id=(value)
if !value.nil? && value.is_a?(String)
self[:likeable_id] = nil
self[:likeable_id_string] = value
else
self[:likeable_id_string] = nil
super(value)
end
end
# Getters
def likeable
if self.likeable_id
return super
elsif !self.likeable_type.nil?
return self.likeable_type.constantize.find(likeable_id_string)
else
return nil
end
end
一旦我覆盖了likeable=
,你会认为不需要likeable_id=
setter ..但似乎是这样。如果有人知道为什么我需要这两个,请告诉我,因为likeable
委托给likeable_id
和likeable_type
我觉得这是一个宝石的用例。我可能很快就会做的事情。如果您希望将此视为宝石(或者如果您认为这是一个可怕的想法),请与我们联系。