Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何通过Rails 3风格的迁移(def更改)识别迁移方向(向上或向下)?_Ruby On Rails_Ruby On Rails 3_Migration_Rails Migrations - Fatal编程技术网

Ruby on rails 如何通过Rails 3风格的迁移(def更改)识别迁移方向(向上或向下)?

Ruby on rails 如何通过Rails 3风格的迁移(def更改)识别迁移方向(向上或向下)?,ruby-on-rails,ruby-on-rails-3,migration,rails-migrations,Ruby On Rails,Ruby On Rails 3,Migration,Rails Migrations,我真的很喜欢Rails 3风格的迁移,即一个change方法足够智能,可以识别迁移是否正在安装或回滚,因此我不必编写up和down方法来相互镜像。但我有这样一种情况,当迁移回滚时,我需要跳过一些代码(更新我正在添加的counter\u cache列) 我看了一下,但第5节末尾的例子也有同样的问题: class AddFuzzToProduct < ActiveRecord::Migration class Product < ActiveRecord::Base end

我真的很喜欢Rails 3风格的迁移,即一个
change
方法足够智能,可以识别迁移是否正在安装或回滚,因此我不必编写
up
down
方法来相互镜像。但我有这样一种情况,当迁移回滚时,我需要跳过一些代码(更新我正在添加的
counter\u cache
列)

我看了一下,但第5节末尾的例子也有同样的问题:

class AddFuzzToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end
  def change
    add_column :products, :fuzz, :string
    Product.reset_column_information
    Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
  end
end
class AddFuzzToProduct'fuzzy'}
结束
结束
回滚此迁移时,不需要更新
fuzz
字段。有什么办法可以预防吗


我试着查看
Product.column\u names
,但由于Rails足够聪明,可以执行反向迁移,所以更新是在删除列之前执行的。此外,当定义了
change
方法时,任何
up
down
方法似乎都会被忽略。还有其他想法吗?

在这种情况下,我认为您必须像往常一样使用
up
down
方法。别担心,尽管在Rails 3中添加了
change
,但据我所知,这些方法并不适用于砧板。必要时继续使用它们

编辑:这里有一个选项:覆盖
migrate

class AddFuzzToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end

  def change
    add_column :products, :fuzz, :string
  end

  def migrate(direction)
    super # Let Rails do its thing as usual...

    if direction == :up # ...but then do something extra if we're going 'up.'
      Product.reset_column_information
      Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
    end
  end
end
class AddFuzzToProduct'fuzzy'}
结束
结束
结束

想法?

这里有一个讨厌的想法:
@connection
是下潜时的命令记录器

def change
    add_column :products, :fuzz, :string
    unless @connection.kind_of?(ActiveRecord::Migration::CommandRecorder)
        Product.reset_column_information
        Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
    end
end
我没试过。很明显,您不在Rails API的范围内,因此它可能随时中断


如果只有更改方法具有确定迁移方向的合法方法…

仅供将来参考,那么对于Rails 4来说,最好的方法是使用可逆:

def change
  # ...change code...

  reversible do |dir|
    dir.up do
      # ...up-only code...
    end
  end
end

请参见rails 3.x中的

,您也可以这样做

class AddFuzzToProduct < ActiveRecord::Migration
  class Product < ActiveRecord::Base
  end
  def change
    add_column :products, :fuzz, :string
    unless reverting?
      # Do this only when direction is up
      Product.reset_column_information
      Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
    end
  end
end
class AddFuzzToProduct'fuzzy'}
结束
结束
结束

我知道我可以定义
向上
向下
而不是
更改
,但如果可能的话,我更喜欢使用
更改
,因为这样可以减少重复。但如果没有其他选择,我想我将不得不使用它们:(@szeryf看一下我更新的答案。希望这对你有用,而且我认为它对于
ActiveRecord::Migration
的API应该非常健壮。这对我来说非常有效;谢谢!在我的情况下,我必须使用一些SQL魔法来根据现有数据将数据插入表中。这样做太耗时了对具有大量记录的现有生产数据执行代码中的操作。可能的话,您可能只需要进行两次迁移?这是所有上述建议中最干净的方法!它也适用于Rails 4.x。并非所有版本的Rails都不推荐使用up和down方法,它们需要这样做。这里提供的所有解决方案都不好因为它们不会被遗忘,而且有难闻的气味,解决问题的最好方法就是写下正确的上下方法