Обновление столбца ActiveRecord в таблице A на основе соответствующего столбца в таблице B - PullRequest
0 голосов
/ 04 февраля 2020

Без каких-либо необработанных SQL я хотел бы иметь возможность выполнить определенную денормализацию с помощью миграции ActiveRecord. Я создаю новый незаполненный столбец в одной таблице:

add_column :table_A, :some_data, :integer, :default => nil

Теперь, :table_A уже имеет ссылку на :table_B через has_many в :table_B модель класса. :table_B также уже имеет столбец :some_data. Я хочу, чтобы столбец :table_A :some_data заполнялся значениями в том же столбце в соответствующих :table_B строках (редактирование: один раз, за ​​одну миграцию, а не непрерывно) , без использования al oop (я хочу, чтобы полученная операция обновления была одним оператором). Я пытаюсь перемещаться по документации ActiveRecord, чтобы определить, как это сделать, но у меня ничего не получается.

https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/update_all указывает мне, как выполнить обновление, где находится получатель одной таблицы, но я не вижу, как получить данные из соответствующей строки в другой таблице. https://apidock.com/rails/ActiveRecord/QueryMethods/joins указывает мне, как выполнить объединение в AR, но я не вижу, как затем выполнить обновление в результирующем наборе данных, потому что я не знаю, как отличить gui sh между двумя таблицами в параметре до update_all. То есть, если я напишу TableA.joins(:table_b).update_all(...), что я поставлю вместо ... там?

РЕДАКТИРОВАТЬ: есть действительно странный набор ограничений в этой задаче, что я не рад тому, что мне нужно работать внутри. Если бы я мог изменить обстановку так, чтобы их не было на месте, я бы сделал это, но я не могу. (Честно говоря, в этом случае я полностью избавился бы от Rails.)

Мы используем миграции AR в средах dev и QA, но запускаем SQL вручную при подготовке и производстве. (Нет, я тоже не понимаю это решение, но я не могу его контролировать.) Это означает, что я хотел бы, чтобы все, что я пишу в миграции AR, детерминистически генерировало тот же SQL независимо от данных, присутствующих в БД в то время, когда генерируется SQL (через гем lol_dba), что, в свою очередь, означает отсутствие циклов, потому что результирующий SQL зависит от данных.

Как мне кажется из этих ответов и из В другом исследовании это означает, что мне нужно написать SQL отдельно для выполнения нужного мне распространения данных, а не как часть миграции. Если бы мы не были в этой странной установке, в которой производственный процесс генерировал SQL для выполнения миграций, эта задача была бы намного проще, и в принципе любого из опубликованных ответов было бы достаточно.

1 Ответ

0 голосов
/ 04 февраля 2020

Вы можете сделать это в консоли rails или в задаче rake, а не в миграции:

  TableA.all.map{ |a| a.update(some_data: a.table_b.some_data) }

Например, если TableA равно Child и TableB равно Father, а some_stuff равно nationality:

  Child.all.map{ |child| child.update(nationality: child.father.nationality) }

Для дальнейших созданий экземпляров TableA вам, безусловно, потребуется обработать это в контроллере (надлежащим образом) или в модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...