ruby-on-rails - ActiveRecord 模型实例上的陈旧关联数据?

标签 ruby-on-rails ruby activerecord ruby-on-rails-2

我使用的是 Rails 2,并且在此应用程序中,Project 模型和 Schedule 模型之间存在一对多关联。

当各种事物的属性发生变化时,我有一个观察者来检查,作为响应,它迭代一个哈希数组,用它来填充新的 Schedule 实例。

每个 Schedule 实例都应该有一个属性,disp_order,它最终会告诉前端在列表中显示它们时在哪里显示它。 disp_order 在将计划添加到项目时填充,因此它比当前最高 disp_order 多 1。

问题出在观察者的迭代中。当我遍历充满 Schedule 数据的哈希数组时,每次迭代都应将 disp_order 计算为比前一个更高的值,以说明 Schedule 它刚刚添加。然而,在实践中,它不会——除非我在迭代中间使用 project = Project.find(project.id) 刷新 Project 对象,或者否则它似乎总是计算 disp_order 的相同最大值,并且没有要继续执行的那些 Schedule 实例的准确列表。

有更好的方法吗? (注意:我的意思是有没有更好的方法,这样我就不必告诉项目重新找到自己。有很多地方我正在积极清理后面的其余代码,但是对于这个问题我真的只对这一行和影响它的事情感兴趣。)

项目.rb

class Project < ActiveRecord::Base
  # ...
  has_many :schedules, :dependent => :destroy
  # ...
  belongs_to :data, :polymorphic => true, :dependent => :destroy
    accepts_nested_attributes_for :data
  # ...

日程表.rb

class Schedule < ActiveRecord::Base
  belongs_to :project, :include => [:data]
  # ...

project_event_observer.rb

class ProjectEventObserver < ActiveRecord::Observer
  # ...          
  def perform_actions(project, actions)
    # ...
    actions.each { |action|
      action.each { |a_type, action_list|
        action_list.each { |action_data|
          self.send(action_type.to_s.singularize, action_data, project)
          project = Project.find(project.id) #My question is about this line.
        }
      }
    }
  # ...

上述迭代的示例操作

[    
  {:add_tasks => [
    {:name => "Do a thing", :section => "General"},
    {:name => "Do another thing", :section => "General"},
   ]
  },
  # More like this one.
]

接收其余 Action 数据的观察者方法

def add_task(hash, project)
  # ...
  sched = Schedule.new
  hash.each { |key, val|
    # ...
    sched.write_attribute(key, val)
    # ...
  }
  sched.add_to(project)
end

日程表.rb

def add_to(proj)
  schedules = proj.schedules
  return if schedules.map(&:name).include?(self.name)
  section_tasks = schedules.select{|sched| sched.section == self.section}
  if section_tasks.empty?
    self.disp_order = 1
  else
    self.disp_order = section_tasks.map(&:disp_order).max + 1 #always display after previously existing schedules
  end
  self.project = proj
  self.save
end

最佳答案

您遇到此问题是因为您正在处理内存中缓存的对象。

看看 association documentation .

您可以在 Schedule 模型的 add_to 函数中传递 true 参数以重新加载查询。

其他选项将包括 inverse_of 但您无法使用它,因为您使用的是多态关联,如文档所述。

关于ruby-on-rails - ActiveRecord 模型实例上的陈旧关联数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23689741/

相关文章:

ruby-on-rails - rails 观察者自定义回调

mysql - 如何高效地从 Rails 中的大表中获取所有行?

ruby-on-rails - 在 Rails 3 中按数组索引选择对象

ruby-on-rails - 如何建立一对多的关系?

ruby-on-rails - 在 Dockerized 应用程序上安装 Ruby Gem

ruby-on-rails - bundle 使用了错误的 ruby​​ 版本

ruby-on-rails - 在编辑操作中上传图像的回形针输入和预览

ruby-on-rails - Rails 根据集合大小多次渲染部分

ruby - 访问 ruby​​ 中的对象内存地址..?

ruby-on-rails - Rails事件记录的 'where'方法异常