Удалить несколько таблиц в одном запросе с помощью join in rails 5

Это мой запрос в рельсах, я хочу удалить записи из таблицы feed и feed mappings, которые соответствуют определенным условиям в одном запросе. Если я использую destroy_all, он удаляет элементы один за другим, сначала он удаляет канал, а затем feed_mappings для каждой записи, тогда как Если я могу просто изменить оператор Select в результирующем запросе на Delete feed, feed_mappings, я могу удалить все одним запросом. Помогите решить эту проблему одним запросом.

Feed.joins(:feed_mappings)
          .joins('inner join notifications on notifications.id = feed_mappings.source_id')
          .joins('inner join user_feedbacks on user_feedbacks.source_id = notifications.picked_for_company')
          .joins('inner join user_feedback_contexts on user_feedback_contexts.user_feedback_id = user_feedbacks.id')
          .where(user_feedbacks: {source_type: 'Company', user_id: user.id},
                 user_feedback_contexts: {context: 'block'},
                 notifications: {user_id: user.id},
                 feed_mappings: {source_type: 'Notifications::Notification'})

Это порождает

SELECT `feeds`.* FROM   `feeds` 
   INNER JOIN `feed_mappings` 
           ON `feed_mappings`.`feed_id` = `feeds`.`id` 
   INNER JOIN notifications 
           ON notifications.id = feed_mappings.source_id 
   INNER JOIN user_feedbacks 
           ON user_feedbacks.source_id = notifications.picked_for_company 
   INNER JOIN user_feedback_contexts 
           ON user_feedback_contexts.user_feedback_id = user_feedbacks.id 
   WHERE  `user_feedbacks`.`source_type` = 'Company' 
   AND `user_feedbacks`.`user_id` = 6 
   AND `user_feedback_contexts`.`context` = 'block' 
   AND `notifications`.`user_id` = 6 
   AND `feed_mappings`.`source_type` = 'Notifications::Notification' 

Что я хочу вместо этого

DELETE `feeds`, `feed_mappings` FROM   `feeds` 
   INNER JOIN `feed_mappings` 
           ON `feed_mappings`.`feed_id` = `feeds`.`id` 
   INNER JOIN notifications 
           ON notifications.id = feed_mappings.source_id 
   INNER JOIN user_feedbacks 
           ON user_feedbacks.source_id = notifications.picked_for_company 
   INNER JOIN user_feedback_contexts 
           ON user_feedback_contexts.user_feedback_id = user_feedbacks.id 
   WHERE  `user_feedbacks`.`source_type` = 'Company' 
   AND `user_feedbacks`.`user_id` = 6 
   AND `user_feedback_contexts`.`context` = 'block' 
   AND `notifications`.`user_id` = 6 
   AND `feed_mappings`.`source_type` = 'Notifications::Notification' 

Какая база данных? Реальный внешний ключ внутри базы данных с on delete cascade может быть вариантом.

mu is too short 13.09.2018 19:04

Какая связь между feed и feed_mappings? Могли бы мы увидеть их модели?

John Skiles Skinner 13.09.2018 19:07

@JohnSkilesSkinner feed_mapping имеет внешний ключ с именем feed_id для подачи таблицы

rajat 13.09.2018 19:39

@muistooshort mysql, каскад удаления - хорошая идея, но это может помешать хукам, которые у нас уже есть в моделях.

rajat 13.09.2018 20:14

Если у вас есть хуки, AR должен будет загрузить все зависимые модели, чтобы запустить хуки в той среде, которую они ожидают. Есть причины, по которым логика часто принадлежит базе данных.

mu is too short 14.09.2018 03:34
0
5
98
1

Ответы 1

Все соединения усложняют ситуацию, но работает ли следующее?

Feed.joins(:feed_mappings)
          .joins('inner join notifications on notifications.id = feed_mappings.source_id')
          .joins('inner join user_feedbacks on user_feedbacks.source_id = notifications.picked_for_company')
          .joins('inner join user_feedback_contexts on user_feedback_contexts.user_feedback_id = user_feedbacks.id')
          .where(user_feedbacks: {source_type: 'Company', user_id: user.id},
                 user_feedback_contexts: {context: 'block'},
                 notifications: {user_id: user.id},
                 feed_mappings: {source_type: 'Notifications::Notification'}).delete_all

FeedMappings.joins('inner join notifications on notifications.id = feed_mappings.source_id')
            .joins('inner join user_feedbacks on user_feedbacks.source_id = notifications.picked_for_company')
            .joins('inner join user_feedback_contexts on user_feedback_contexts.user_feedback_id = user_feedbacks.id')
            .where(user_feedbacks: {source_type: 'Company', user_id: user.id},
                   user_feedback_contexts: {context: 'block'},
                   notifications: {user_id: user.id},
                   feed_mappings: {source_type: 'Notifications::Notification'}).delete_all

Это два разных запроса, я хочу сделать это в одном запросе, так как мы знаем, что это возможно в необработанном sql.

rajat 13.09.2018 20:15

Другие вопросы по теме