私はユーザーが放送番組やエピソードを追跡できるRailsアプリを持っています。多態性は動的クラスと関連しています(他の関係から取られました)
(まだ)視聴していない番組を追跡するプロセスを簡素化するために、ユーザーは自分のアカウントを他のサービスと同期させることができます。ユーザー設定ページで、同期するサービスを選択できます。
同期するために、私は自分のプロファイルを他のサービスからロードし、最後の同期からの変化を検出し、それに応じてDBを更新するアルゴリズムを実行します。最後の同期ステータスを保存するために、Show IDごとに、ショー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
Iが多型の関係にそれを回すことができますが、私は本当に含まれているために、テキスト列を追加する必要がありますする必要はありません(ユーザーが同期サービスを切り替えるために、そのユーザーのすべてのUsersSyncIdStatusesが破棄されるため、ユーザーはUsersSyncIdStatusesに2つ以上のサービスタイプを持つことはありません)。
アイデア?前もって感謝します!
多態性の関係を試していないというあなたの推論や、「has_many:through」さえ理解できません。 'sync_method'は、あなたが典型的にモデルで見つけたものの型です。 'has_many'のような関連はRuby文であり、条件付きで制御することができます。あなたはデータベースにそれをコーディングするのが難しいようですが、なぜですか? –
多相関連では、関係のモデル名を含むテキスト列を 'users_sync_id_statuses'テーブルに追加する必要があります。 1人のユーザーが何千もの 'users_sync_id_statuses'行を持ち、それらのすべてが同じモデルクラスとの関係を持つため、それらのすべての1つに列を追加することはデータベーススペースの膨大な浪費です...問題は各ユーザーはその関係の異なるモデルを持つ可能性があり、関係モデルのユーザーオブジェクトを自動的に照会する関係を、すべての行に格納するのではなく、必要としました。 – rpinheiro
私は、正直言って、私はそれらを使用して終了しませんでした。しかし、私の推薦は、関係宣言をデータベースから取り除こうとすることに至りました。外部キーを保持し、ActiveRecordアソシエーションを使用してクエリを構築します。このアプローチについてのご予約はありますか? –