Как мне обновить записи в рельсах 3 на основе значений псевдонимов ассоциации (или их отсутствия)? - PullRequest
0 голосов
/ 18 октября 2011

У меня есть модель, которая ассоциируется непосредственно с собой в некоторых конкретных контекстах, вроде как:

class Node < ActiveRecord::Base
  belongs_to :next_node, :class_name => 'Node'
end

До сих пор это работало превосходно. Однако недавно мы добавили ограничение для исправления ошибки при удалении узла - любые узлы, указывающие на него как «следующий узел», необходимо обновить, чтобы отразить, что у него больше нет следующего. Я добавил условие after_destroy:

class Node < ActiveRecord::Base
  after_destroy :clean_tree

  def clean_tree
    Node.where(:next_node_id => self.id).update_all(:node_type => 'leaf')
  end
end

Игнорирование лучших реализаций этого (это очень упрощенный пример, выявляющий сложности, которые делают эту модель данных необходимой), это работает как ожидалось. Для вновь созданных структур. Но я пытаюсь написать миграцию для обновления старых структур. Вот тут и приходит мой вопрос. Я попробовал следующий код. Но я не смог заставить работать соединение за одним столом:

Node.joins(:next_node).where(:next_node => { :id => nil }).update_all(:node_type => 'leaf')

Сбой. Он считает соединение допустимым, но SQL не добавляет соединение, а предложение where не распознает next_node. Он генерирует что-то вроде

UPDATE nodes SET node_type = 'leaf' WHERE (next_node.id IS NULL)

Понятно, что это не вызывает ассоциации.

Я пробовал несколько вариантов, используя next_node, next_nodes, node, node. Ничто не похоже на работу. Приведенный выше пример - единственный, который делает его достаточно далеко, чтобы генерировать sql. Все остальное ошибается до того, как рельсы могут зайти так далеко. Что я делаю не так?

...