首页 > 解决方案 > 从控制器操作运行 rails 迁移文件

问题描述

我有这个 Rails 迁移文件(123blablabla.rb),我想在创建和更新操作时运行它。我怎么知道的。

移民:

class CombineItemsInSale < ActiveRecord::Migration[5.1]
  def up
    Sale.all.each do |sale|
      sums = sale.items.group(:product_id).sum(:quantity)
      sums.each do |product_id, quantity|
        if quantity > 1
          sale.items.where(product_id: product_id).delete_all

          item = sale.items.build(product_id: product_id)
          item.quantity = quantity
          item.save!
        end
      end
    end
  end

  def down
    #split items with a quantity of 1 or more into multiple items
    Item.where("quantity>1").each do |item|
      item.quantity.times do
        Item.create(
          sale_id: item.sale_id,
          product_id: item.product_id,
          quantity: 1
        )
      end
      # remove original line item
      item.destroy
    end
  end
end

标签: ruby-on-railsmigration

解决方案


迁移用于随着时间的推移改变您的数据库模式,您不应该以这种方式使用迁移。

首先,请更新您的问题,您的问题应该是因为您现在提出的问题没有任何意义,人们会感到困惑。

现在回到主题

您应该基于事务更新模型,而不是对所有数据运行进程。每次创建/更新项目时,使用回调来拆分

class Item < ActiveRecord::Base
  belongs_to sale
  after_commit :split
  ...
  def split
    self.sale.split_items
  end
end

class Sale < ActiveRecord::Base
  has_many items
  ...
  def split_items
    products_items = self.items.group_by(&:product_id)
    products_items.each do |product_id, items|
      if items > 1
        quantity = items.sum(:quantity)
        items.delete_all
        Item.create(product_id: product_id, quantity:quantity)
      end
    end
  end
end

注意这不是最佳的方法,但它会完成工作。


推荐阅读