【问题标题】:inconsistent results from rails console v. dev UXrails console v.dev UX的结果不一致
【发布时间】:2015-07-17 13:34:04
【问题描述】:

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

当我在 c9.io 托管的 Rails 开发用户界面中创建一个 List 时,它的行为符合预期。当我在控制台中创建一个列表时,它没有; 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

但大多数情况下,我很困惑,如果有任何提示,我将不胜感激。

【问题讨论】:

    标签: ruby-on-rails service console development-environment cloud9-ide


    【解决方案1】:

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

    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
    

    可以即时计算的东西应该被计算出来,如果你真的需要,只将它们存储为一种优化形式。它使您的业务领域更容易调试和支持。维护状态是最后的手段!

    【讨论】:

    • 感谢@ilan 的启发性和启发性回答。你甚至包括amount,令我高兴。我仍然在学习把东西放在哪里,并试图让我的模型和控制器保持苗条(正如你从我的其他问题/答案中看到的那样),但是关于服务的要点。你说得对,我不需要存储这些值,这甚至不是我的目标。 rails n00b 的最大挑战似乎是知道 where 放置逻辑。作为记录,我并不是真的来自任何堆栈(它是全新的),所以我将您的 Java 评论视为一种奇怪的恭维。 ;)
    • @Leo,没问题,继续保持原样,一切都会好起来的。 java堆栈不是侮辱。由于 Java Bean 的限制,这是一种利用服务对象的编码风格。多年来,它被证明是一种反模式,但它仍然相当普遍。
    • 有趣的回复:豆类,谢谢你的解释。我会继续加油的!
    • 我已不再接受您的回答,因为在我对更精简和更高效的代码感到兴奋时,我没有注意到我原来的问题仍然存在。创建新列表时仍在控制台中,total_calories 等于 0;而当我通过 c9.io 开发用户界面创建列表时,total_calories 的行为与预期一致。关于如何追踪这种奇怪的明显无错误的行为有什么想法吗?
    • 如果还没有答案,我已经确定了问题:数量通过 write_list 服务添加到列表中,该服务由列表控制器调用,仅在通过用户创建列表时发生界面。在控制台中,没有 addlist 表单,因此没有 Quantity 创建!我可以通过将 Quantity 创建移动到 List 模型中的回调来进行重构,以确保永远不会创建空 List,这取决于我是否决定 Quantity 添加对于 List 创建是必不可少的。我必须将其视为设计问题。无论如何,我认为我现在走在了正确的轨道上。
    猜你喜欢
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 2021-03-27
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多