недавно у меня была миграция, которая добавляет столбец user_id
в таблицы watch_events. и поэтому я хочу изменить модели watch_event, чтобы они обрабатывали own_to, но с множественным подходом
create_table 'users', force: :cascade do |t|
t.integer 'id'
t.integer 'customer_id'
end
create_table 'watch_events', force: :cascade do |t|
t.integer 'customer_id'
t.integer 'user_id'
end
ранее
class WatchEvent < ApplicationRecord
belongs_to :user, foreign_key: :customer_id, primary_key: :customer_id
end
что я хочу:
watch_event.customer_id
присутствует, я хочу использовать belongs_to :user, foreign_key: :customer_id, primary_key: :customer_id
watch_event.customer_id
нет, я хочу использовать обычный belongs_to :user
как я могу добиться этого в модели watch_event?
Если я правильно понял ваш вопрос, то вы ищете Полиморфную ассоциацию.
Если вы видите приведенный ниже код, он в основном создает два столбца в таблице watch_events
, watcher_type
и watcher_id
. Затем belongs_to :watcher
использует столбец watcher_type
, чтобы определить, с какой моделью он должен ассоциироваться.
create_table 'watch_events', force: :cascade do |t|
t.references 'watcher', polymorphic: true, null: false
end
class WatchEvent < ApplicationRecord
belongs_to :watcher, polymorphic: true
end
Я не думаю, что Rails поддерживает «запасные внешние ключи» для ассоциаций. Однако вы можете написать простую оболочку для своей проблемы. Во-первых, дважды свяжите свой класс WatchEvent
с пользовательской моделью, используя два ключа и два «внутренних» имени ассоциации (:user_1
и :user_2
). Затем добавьте «считыватель виртуальных ассоциаций» (user
) и «установщик виртуальных ассоциаций» (user=(new_user)
):
class WatchEvent < ApplicationRecord
belongs_to :user_1,
class_name: 'User',
foreign_key: :customer_id
belongs_to :user_2,
class_name: 'User',
foreign_key: :user_id
def user
user_1 || user_2
end
def user=(new_user)
self.user_1 = new_user
end
end
С этим решением удовлетворяются требования «использовать customer_id
для поиска пользователя» и «использовать user_id
в качестве резервного внешнего ключа, если customer_id
является nil
или не дает результата». Это происходит в методе чтения ассоциаций user
. Когда есть метод чтения, вам понадобится метод установки, которым является user=()
. Не стесняйтесь проектировать внутренности сеттера по мере необходимости, мое просто предложение.
Кстати: вам может потребоваться повторно добавить декларацию иностранного primary_key
. Я опустил это для ясности.
кажется, это поможет мне в том, что мне нужно, спасибо
это не то, что я имею в виду. дело в том, что я хочу перейти от
belongs_to :user, foreign_key: :customer_id, primary_key: :customer_id
кbelongs_to :user
, но из-за обратной совместимости старые данные watch_events будут иметь нулевой user_id