轨道活动记录对象。 "Sum"行为出乎意料



我正在阅读 Rails 4 测试处方。我对"总和"方法有一个有趣的观察。书中有两个模型:项目和任务

class Project < ActiveRecord::Base
  has_many :tasks
  ...
end
class Task < ActiveRecord::Base
  belongs_to :project
  ...
end
#Rspec code
describe "estimates" do
  let(:project) { Project.new }
  let(:newly_done) { Task.new(size: 3, completed_at: 1.day.ago)}
  let(:old_done) { Task.new(size: 2, completed_at: 6.months.ago)}
  let(:small_not_done) { Task.new(size: 1)}
  let(:large_not_done) { Task.new(size: 4)}
  before(:each) do
    project.tasks = [newly_done, old_done, small_not_done, large_not_done]
    othertasks = [newly_done, old_done,small_not_done, large_not_done]
    puts "Size of project is #{project.tasks.sum(&:size)}" # line 1 <- 0
    puts "Size of othertasks is #{othertasks.sum(&:size)}" # line 2 <- 10
  end
end

如注释所示,第 1 行打印 0,第 2 行打印 10(预期结果)。我也尝试使用let!代替let,并得到了相同的结果。我想知道这种不一致行为的原因是什么。我正在使用 ruby 2.2 和 Rails 4.2.1

编辑: 我试过: 1. 添加任务后保存项目

   ...
   project.tasks <<  [newly_done, old_done, small_not_done, large_not_done]
   project.save
   ... 

2. 使用创建而不是新建

      ...
      let(:project) { Project.create }
      let(:newly_done) { Task.create(size: 3, completed_at: 1.day.ago)}
      let(:old_done) { Task.create(size: 2, completed_at: 6.months.ago)}
      let(:small_not_done) { Task.create(size: 1)}
      let(:large_not_done) { Task.create(size: 4)}
      ...

并且仍然得到了相同的结果。

事实证明,

我需要在执行聚合操作之前添加一个to_a。 工作代码是:

 #Rspec code
  describe "estimates" do
    let(:project) { Project.new }
    let(:newly_done) { Task.new(size: 3, completed_at: 1.day.ago)}
    let(:old_done) { Task.new(size: 2, completed_at: 6.months.ago)}
    let(:small_not_done) { Task.new(size: 1)}
    let(:large_not_done) { Task.new(size: 4)}
    before(:each) do
      project.tasks = [newly_done, old_done, small_not_done, large_not_done]
      othertasks = [newly_done, old_done,small_not_done, large_not_done]
      puts "Size of project is #{project.tasks.to_a.sum(&:size)}" # line 1 <- 10
      puts "Size of othertasks is #{othertasks.sum(&:size)}" # line 2 <- 10
    end
  end

请注意第 1 行中的to_a

最新更新