来自 rails console v. dev UX 的不一致结果

inconsistent results from rails console v. dev UX

创建数量列表后,列表属性 total_calories 应更新为与列表关联的所有 calories 的总和。列表和食物关联 has_many :through 个数量,每个食物都有一个 calories 属性。

当我在 c9.io 托管的 rails 开发用户界面中创建列表时,它的行为符合预期。当我在控制台中创建一个列表时,它没有; total_calories 没有更新。怎么会这样?

我将不胜感激有关调查内容的任何提示,因为我从未遇到过控制台和开发用户界面之间不一致的问题。

服务对象count_calories.rb

class CountCalories

  def initialize(list)
    @list=list
  end

  def count
    @calories = 0
    @list.quantities.each do |q|
      @calories += Food.find(q.food_id).calories
    end
    @list.update!(total_calories: @calories)
    @list.save!
  end

end

List控制器中的create方法:

def create
  @list = WriteList.new(list_params).write
  if @list.save
    flash[:success] = "A list has been created!"
    CountCalories.new(@list).count
    redirect_to @list
  else
    render 'new'
  end
end

服务对象write_list.rb,如果有帮助的话:

class WriteList

  def initialize(params)
    @params=params
  end

  def write
    ActiveRecord::Base.transaction do
      list = List.new(days: @params[:days], name: @params[:name])
      list.save!
      3.times do
        food1 = Food.all.sample.id
        Quantity.create!(food_id: food1, list_id: list[:id], amount: 1+rand(6))
      end
      list.save!
      return list
    end
    rescue
      return List.new(days: @params[:days], name: @params[:name])
  end

end

我唯一能想到的是,可能跟创建的迁移有关total_calories:

class AddTotalCaloriesToLists < ActiveRecord::Migration
  def change
    add_column :lists, :total_calories, :integer, :default => 0
  end
end

但大多数情况下,我感到困惑,希望得到任何提示。

我相信你对你的问题设计过度了。您似乎来自 Java 网络堆栈,并且它以 rails 的方式不同地完成。如果不需要,请避免使用服务对象。

class Food < ActiveRecord::Base
  validates_presence_of :calories

  has_many :lists, through: :food_lists, :dependent: :destroy
end

class FoodList < ActiveRecord::Base
  belongs_to :food
  belongs_to :list
  validates_presence_of: :amount, :food, :list
end

class List < ActiveRecord::Base
  has_many :food_lists
  has_many :foods, through: :food_lists, dependent: :destroy

  def total_calories
    self.food_lists.map{|fl| fl.amount * fl.food.calories}.sum
  end
end

可以即时计算的东西应该计算,只有在确实需要时才将它们存储为优化形式。它使您的业务领域更容易调试和支持。维持状态是不得已的办法!