Хранение логического бита для отношения многие ко многим
Я пишу систему форумов (на Ruby, использую Sequel), и одно из требований - чтобы пользователи могли "пометить" тему, что примерно соответствует функциям "подписки", поддерживаемым большинством форумов. Я не уверен в том, как сохранить главную роль в базе данных, и особенно в том, как запрашивать помеченные / не помеченные темы для данного пользователя или проверять, помечен ли какой-либо поток.
Любые советы будут с благодарностью, и если вы знаете, как разбираться в Sequel, пример модели будет абсолютно великолепным.
1 ответ
Это очень просто реализовать:
Сначала ваша миграция:
create_table(:subscriptions, ignore_index_errors: true) do
primary_key :id
column :created_at, 'timestamp with time zone'
foreign_key :user_id, :users, null: false, key: [:id], index: true, on_delete: :cascade
foreign_key :thread_id, :threads, null: false, key: [:id], index: true, on_delete: :cascade
end
Ваши модели:
приложение / модели /subscription.rb
class Subscription < Sequel::Model
many_to_one :user
many_to_one :thread
end
приложение / модели /user.rb
class User < Sequel::Model
one_to_many :subscriptions
many_to_many :subscribed_threads,
class: :Thread,
join_table: :subscriptions,
left_key: :user_id,
right_key: :thread_id
end
приложение / модели /thread.rb
class Thread < Sequel::Model
one_to_many :subscriptions
many_to_many :subscribers,
class: :User,
join_table: :subscriptions,
left_key: :thread_id,
right_key: :user_id
end
Запрос следующим образом
# all threads a user is subscribed to
user.subscribed_threads
# all subscribers to a thread
thread.subscribers
# all subscriptions to a thread in the last 3 days
thread.subscriptions.where{created_at >= Date.today - 3}
Я предлагаю также настроить плагин ассоциаций набора данных на всех ваших моделях:
# Make all model subclasses create association methods for datasets
Sequel::Model.plugin :dataset_associations
Затем вы можете составлять и объединять запросы с помощью ассоциаций с условиями:
# all new subscribers for a thread in the last 3 days who are moderators
thread.subscriptions.where{created_at >= Date.today - 3}.user.where(moderator: true)
Есть несколько мощных возможностей фильтрации и запросов: