Реальный активный объект записи. "Сумма" ведет себя неочевидно

97
12

Я читаю Rails 4 Test Prescriptions. У меня было интересное замечание относительно метода "Сумма". Из книги есть две Модели: Проект и Задача

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. с помощью create вместо новых

      ...
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)}
...

и все же получил тот же результат.

спросил(а) 2015-04-15T20:51:00+03:00 6 лет назад
1
Решение
87

Оказывается, мне нужно добавить 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

Обратите внимание на to_a в строке 1.

ответил(а) 2015-04-16T00:54:00+03:00 6 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема