【问题标题】:Can't work before_validation when nested field is delated with cocoon gem嵌套字段与茧宝石相关时无法使用 before_validation
【发布时间】:2018-09-14 05:16:39
【问题描述】:

我有这个带有 cocoon gem 的 order 和 order_detail 的迁移和模型。

class CreateOrders < ActiveRecord::Migration[5.0]
  def change
    create_table :orders do |t|
      t.integer :total_price
      t.timestamps
    end
  end
end

class CreateOrderDetails < ActiveRecord::Migration[5.0]
  def change
    create_table :order_details do |t|
      t.integer :subtotal_price
      t.integer :unit_price
      t.integer :quantity
      t.references :order, foreign_key: true
      t.timestamps
    end
  end
end

class Order < ApplicationRecord
  has_many :order_details, inverse_of: :order, dependent: :destroy
  before_validation :calculate_order_price
  accepts_nested_attributes_for :order_details, :reject_if => :all_blank, :allow_destroy => true

  def calculate_order_price
    order_details.each(&:calculate_order_detail_price)
    self.total_price = order_details.map(&:subtotal_price).sum
  end
end

class OrderDetail < ApplicationRecord
  belongs_to :order
  def calculate_order_detail_price
    self.subtotal_price = unit_price * quantity
  end
end

当我在添加或编辑嵌套字段后保存记录时,效果很好。但如果我编辑以延迟嵌套字段,calculate_order_price 不起作用。

如果有人知道这件事,请告诉我。

【问题讨论】:

    标签: ruby-on-rails cocoon-gem


    【解决方案1】:

    有一个选项:touch 将确保在更新父级设置updated_at(或其他字段)但它不会运行验证。然而,还有一个选项:validate(但不完全确定它会在销毁时被调用):

     belongs_to :order, validate: true 
    

    否则,如果这些不起作用,您可以执行类似的操作

    class OrderDetail < ApplicationRecord 
    
      belongs_to :order 
    
      after_destroy :trigger_parent_validation
    
      def trigger_parent_validation 
        if order.present? 
          order.validate 
        end
      end 
    end 
    

    【讨论】:

    • 感谢您的评论。我试过你的方法,但效果不好。当我保存嵌套字段时,它将显示:无。因此,当 calculate_order_price 运行时,它会汇总所有嵌套字段。我希望 calculate_order_price 求和,除了 display:none 嵌套字段。
    • 你把事情弄糊涂了:display: none 在浏览器中(我们必须保留它,因为 rails 需要知道要删除哪个 order-detail,所以我们“隐藏”元素并设置 @ 987654327@ 标志)。将表单发布到控制器后,只有 then 回调运行。如果你需要在浏览器中更新数字,你应该使用javascript回调cocoon:after-insert和cocoon:after-destroy,它们也可以计算订单价格。
    • 好的,我明白了。我希望 after_validation 运行时不会破坏嵌套字段。我会试试 javascript cocoon:after-remove。谢谢你帮助我。我毕业了,可以联系 cocoon gem 的开发者了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    相关资源
    最近更新 更多