使用Globalize

时间:2015-12-10 07:59:12

标签: ruby-on-rails ruby migration

几年前(2013年)我使用Globalize 0.3.0,Rails 3.2.21,Ruby 2.1.6编写了一个全局化我的模型的一个字段的迁移:

class CreateMyModelTranslationTable < ActiveRecord::Migration
  def up
    change_table :my_model do |t|
      t.remove  :name
    end
    MyModel.create_translation_table! name: :string
  end

  def down
    change_table :my_model do |t|
      t.string :name
    end
    MyModel.drop_translation_table! 
  end
end

我添加了相应的翻译属性:

translates :name, required: true

现在我想添加名为title的第二个全球化属性,所以我将此行添加到MyModel:

translates :title

即使在编写第二个迁移脚本之前,我也会删除数据库并执行所有迁移。

bundle exec rake db:drop db:create db:migrate

我注意到我在2013年写的迁移脚本失败了。这怎么可能?这就是我现在所知道的。

我的2013迁移脚本中的方法create_translation_table!正在向翻译表添加模型中找到的所有可翻译字段,即:name:title。恕我直言,这有点奇怪,因为这段代码实际上是执行数据库更改,可能在创建迁移后添加到模型中。

Globalize gem尝试猜测:title的类型并且它似乎失败了,因为我在执行2013迁移脚本时遇到了这个错误:

Bad field type for field :title (nil), should be :string or :text

我正在寻找实现这些选择的方法:

  • 防止Globalize在运行2013迁移脚本时为:title创建列,并创建2015迁移脚本以添加此列no te转换表(我认为此选项更好)
  • 了解如何在模型中指定:title是一个字符串(我已经尝试translates :title, :string并且似​​乎不起作用)。

1 个答案:

答案 0 :(得分:2)

之前我遇到过类似的问题,其中一个解决方案是始终在迁移中指定已翻译的属性:

Location
.find({
  'position': {
    $near: {
      $geometry: {
        type: 'Point',
        coordinates: [lat, lng]
      },
      $minDistance: 0,
      $maxDistance: 20000
    }
  }
})
.populate({
  path: 'user',
  match: {
    'skills': {
      $elemMatch: {
        'object.slug': 'cleaning'
      }
    }
  },
  options: {
    limit: 5
  }
})
.deepPopulate('user.skills.object')
.exec(callback);

还建议完全避免全局化生成器并手动创建转换表:

def up
  MyModel.translated_attribute_names = [:name]
  MyModel.create_translation_table! name: :string
end