我有一个Rails应用程序,用户可以跟踪播放节目和剧集。多态belongs_to与动态类的关联(取自其他关系)
为了简化跟踪的(没有)观看节目的过程中,用户能够将其帐户与其他服务同步。他们可以在他们的用户设置页面中选择他们想要同步的服务。
要同步,我从其他服务加载他们的个人资料,然后通过检测从最后的同步变化,并相应地更新DB的算法运行。为了存储最后的同步状态,对于每个Show ID,我创建一个“UsersSyncIdStatus”对象,该对象存储节目ID以及同步服务中该节目的当前状态。
注意,服务不使用同一个节目ID作为我的网站,这意味着我有,我可以用它来从他们的表演标识“转换”我的节目ID的表。由于每个服务提供的信息不同,它们必须存储在不同的表中。
现在,这是(的简化版本)DB模式的设置方式:
create_table "service1_ids", force: :cascade do |t|
t.integer "service_id", null: false
t.integer "show_id", null: false
[...]
end
create_table "service2_ids", force: :cascade do |t|
t.integer "service_id", null: false
t.integer "show_id", null: false
[...]
end
create_table "users_sync_id_statuses", force: :cascade do |t|
t.integer "user_id"
t.integer "service_id", null: false
t.integer "sync_status", default: 0, null: false
t.datetime "sync_date", null: false
[...]
end
create_table "users", force: :cascade do |t|
[...]
t.datetime "synced_at"
t.boolean "sync_enabled", default: false, null: false
t.integer "sync_method", default: 0, null: false
[...]
end
特别地,users.sync_method
是存储用户已经选择用于同步的服务的枚举:
SYNC_METHODS = {
0 => {
symbol: :service1,
name: 'Service1',
model_name: 'Service1Id',
show_scope: :service1_ids
}
1 => {
symbol: :service2,
name: 'Service2',
model_name: 'Service2Id',
show_scope: :service2_ids
}
}
这意味着我只需做SyncHelper::SYNC_METHODS[current_user.sync_method][:model_name]
即可轻松知道特定用户的ID的型号名称。
现在的问题是,我怎么能有“users_sync_id_statuses”和“serviceN_ids”之间的关系?为了知道“service_id”列对应哪个类,我必须“询问”用户模型。
我现在有它实现的方法:
class User
def sync_method_hash
SyncHelper::SYNC_METHODS[self.sync_method]
end
def sync_method_model
self.sync_method_hash[:model_name].constantize
end
end
class UsersSyncIdStatus
def service_id_obj
self.user.sync_method_model.where(service_id: self.service_id).first
end
end
然而,UsersSyncIdStatus.service_id_obj
是一种方法,而不是一个关系,这意味着我不能做所有的花哨的东西有关系允许。举例来说,我不能轻易抢UsersSyncIdStatus特定用户,并显示ID:
current_user.sync_id_statuses.where(service_id_obj: {show_id: 123}).first
我可以把它变成一个多态的关系,但我真的不希望有添加一个文本列包含类名,当它从每个用户的角度看是“常量”时(对于用户切换同步服务,该用户的所有UsersSyncIdStatuses都会被销毁,因此用户的UsersSyncIdStatuses中永远不会有超过1个服务类型)。
任何想法?先谢谢你!
我并不真正理解你没有尝试多态关系,甚至是'has_many:through'的理由。看起来'sync_method'就是你通常在模型中找到的东西。请记住像'has_many'这样的关联是Ruby语句,可以用条件来控制。看起来你很难将其编码到数据库中,但为什么? –
多态关联需要向包含关系模型名称的'users_sync_id_statuses'表中添加文本列。由于单个用户可能有成千上万个'users_sync_id_statuses'行,并且所有这些行都与同一个模型类有关系,所以将它们添加到其中的每一个都是数据库空间的巨大浪费......问题是每个用户可能有不同的关系模型,我想要一个关系自动查询关系模型的用户对象,而不是依赖每个行存储的关系。 – rpinheiro
我看到了,说实话我从来没有结束使用这些。但我想我的建议归结为试图从数据库中删除关系声明;只保留外键,并使用ActiveRecord关联来构建查询。你对这种方法有所保留吗? –