Rails关联 - 级联更新

时间:2009-06-04 21:47:27

标签: ruby-on-rails plugins associations

我有多个类,有许多关联将它们连接在一起,我希望能够获取顶级对象,关闭它,并关闭所有子对象。我需要关闭每个对象,因为我希望能够选择任何父级并让所有父级关闭。

例如(我意识到这可能不存在):

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

有没有人知道实现这个目标的好方法?一个gem /插件是完全可以接受的: - )

非常感谢!

3 个答案:

答案 0 :(得分:0)

很难理解你的目标。如果你能用“关闭”来澄清你的意思,那将会有所帮助。

以下信息可能会回答您的问题。

ActiveRecord通过'save'和'save!'为数据库提供持久性的概念方法。默认情况下,保存父对象时会保存关联对象。

答案 1 :(得分:0)

如果您实际上从未使用destroy方法从数据库中删除行,则可以覆盖destory方法来执行dateClosed然后我相信:dependent => :destroy只调用相关对象的destroy方法

def destroy
   dateClosed = Date.today
end

class Requisition  has_many :shipments, :dependent => :destroy

答案 2 :(得分:0)

我坐下来写了一个小插件来做这件事。我称之为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?),但这是我必须弄清楚的主要代码。希望它可以帮助别人!