Rails Ассоциации - каскадное обновление - PullRequest
0 голосов
/ 05 июня 2009

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

Например (я понимаю, что этого, вероятно, не существует):

class Requisition
  has_many :shipments, :dependent_method => :close
end

class Shipment
  belongs_to :requisition

  has_many :reroutes, :dependent_method => :close
end

class Reroute
  belongs_to :shipment

  has_many :deliveries, :dependent_method => :close
end

class Delivery
  belongs_to :reroute
end

Кто-нибудь знает хорошее решение для достижения этой цели? Драгоценный камень / плагин будет вполне приемлемым: -)

Большое спасибо!

Ответы [ 3 ]

0 голосов
/ 05 июня 2009

если вы на самом деле никогда не удаляете строку из вашей БД с использованием методов уничтожения, вы можете просто перезаписать методы уничтожения, чтобы сделать dateClosed, и тогда я верю: зависимый =>: destroy просто вызывает связанный метод уничтожения объектов

def destroy
   dateClosed = Date.today
end

class Requisition  has_many :shipments, :dependent => :destroy
0 голосов
/ 09 июня 2009

Я сел и написал небольшой плагин для этого. Я называю это acts_as_closable, и он просто добавляет следующий метод к фильтру before_save. Вы должны использовать :autosave => true для каждой ассоциации, с которой хотите работать, но для меня это имело смысл, вместо того, чтобы acts_as_closable автоматически сохранял ассоциацию для вас. Я могу сделать это позже и выпустить код. Вот мясо:

def update_closed_status_of_children
  [self.class.reflect_on_all_associations(:has_many), self.class.reflect_on_all_associations(:has_one)].flatten.each do |assoc|

    # Don't consider :through associations since those should be handled in
    # the associated class
    if not (assoc.options.include? :through)
      attribute = self.class.acts_as_closable_config.closed_attribute
      children = self.send(assoc.name)
      children = Array(children).flatten.compact

      children.each do |child|
        # Check to make sure we're only doing this on something declaring acts_as_closable
        if child.class.included_modules.include? ActsAsClosable
          child.send(:closed_value=, self.closed_value)
        end
      end
    end

  end
end

Я определяю некоторые другие методы (например, :closed_value= и :closed?), но это основной код, который мне пришлось выяснить. Надеюсь, это поможет кому-то еще!

0 голосов
/ 05 июня 2009

Трудно понять вашу цель. Было бы полезно, если бы вы могли уточнить, что вы подразумеваете под словом «закрыть».

Следующая информация может ответить на ваш вопрос.

ActiveRecord имеет концепцию сохранения в базе данных через «сохранить» и «сохранить!» методы. По умолчанию объекты ассоциации сохраняются при сохранении родительского объекта.

...