从控制器操作运行rails迁移文件

时间:2018-05-07 13:23:11

标签: ruby-on-rails migration

我有这个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

1 个答案:

答案 0 :(得分:0)

迁移用于随时间更改数据库架构,不应以这种方式使用迁移。

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

现在回到主题

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

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

注意这不是最佳方式,但它可以完成工作。