【问题标题】:Why Rails data loaded from Fixtures are broken?为什么从 Fixtures 加载的 Rails 数据会损坏?
【发布时间】:2012-10-25 14:41:06
【问题描述】:

我有两个用于区域设置和翻译的固定文件。 语言环境加载正常,但翻译损坏:

夹具

translation_05064:
  id: 5064
  key: control.base_search_users.panel.title
  value: Поиск пользователей
  interpolations: 
  locale: ru
  locale_id: 16
  is_proc: false

成为记录:

#<Translation id: 5064, 
key: "control.base_search_users.panel.title", 
value: "Поиск пользователей", 
interpolations: nil, 
locale: nil, 
locale_id: 1019186233, 
is_proc: false>

由于某种原因 locale 而不是 'ru' 变成 nil,而 locale_ib 而不是 16 变成 1019186233 用于文件中的每个灯具。

我以这种方式加载固定装置:

require 'active_record/fixtures'
ActiveRecord::Fixtures.reset_cache  
fixtures_folder = File.join(Rails.root, 'test', 'fixtures')
fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') }
ActiveRecord::Fixtures.create_fixtures(fixtures_folder, fixtures)

翻译模型

class Translation < ActiveRecord::Base
  validates :key, :uniqueness => {:scope => :locale_id}
  validates :key, :locale, :locale_id, :value, :presence => true
  belongs_to :locale
  attr_accessible :key, :value, :locale_id, :locale
end

迁移

  class CreateTranslations < ActiveRecord::Migration
    def change
      create_table :translations do |t|
        t.string  :key
        t.text    :value
        t.text    :interpolations
        t.string  :locale
        t.integer :locale_id
        t.boolean :is_proc, :default => false
      end
      add_index :translations, [:key, :locale]
    end
  end

我在插入数据库的 test.log 中看到包含损坏的数据。当我使用YAML.load_file 'test/fixtures/translations.yml' 在rails concole 中加载夹具文件时,我得到了正确的哈希数据。

为什么会这样?如何解决? Rails-2.3.8PostgreSql-8.4


更新: 尝试了命名的装置。在 locales.yml 中:

locale_00016:
  id: 16
  code: ru
  name: Русский

并且在 translations.yml 中所有 locale 键值设置为 locale_00016

translation_05064:
  id: 5064
  key: control.base_search_users.panel.title
  value: Поиск пользователей
  locale: locale_00016
  is_proc: false

是的,行得通!

翻译 id 引用了现有且正确的 Locale 记录,但 locale 仍然为零,为了修复它,我运行了 Locale.find_by_code('ru').translations.update_all(:locale =&gt; 'ru')

【问题讨论】:

  • 如果您删除了夹具中的空白interpolations 行,还有问题吗?它可能会导致问题。您可以删除它或将其设置为 ""
  • 我都试过了,删除插值行并指定一个空值''。这并没有解决问题,但是查看日志我发现插入中没有 locale 字段,以防我从 yml 文件中删除 interpolation 行。我感到很困惑。 Fixture Insert (1.5ms) INSERT INTO "translations" ("id", "key", "value", "locale_id", "is_proc") VALUES (5502, 'sites.index.title', 'Сайты', 1019186233, 'f')
  • 如果我从 yml 文件中删除 interpolationslocale_id 行,locale_id 仍然会出现在日志中。 Rails 自己添加:Fixture Insert (0.9ms) INSERT INTO "translations" ("id", "key", "value", "is_proc", "locale_id") VALUES (5503, 'sites.menu.index', 'Сайты', 'f', 1019186233)

标签: ruby-on-rails fixtures


【解决方案1】:

如果设置了locale_id,好像没问题; locale 将在您需要时由 Rails 填充(第一次请求时)。 1019186233是rais在创建fixture时生成的id。

大多数时候,您不需要在夹具中指定 id,rails 会为您生成它们,所以像下面这样的夹具应该没问题(您不应该在 Translation 夹具中同时定义 localelocale_id):

locales.yml:

ru:
  what_ever_attr: value
  ...

translations.yml:

ru_title_translation:
  key: control.base_search_users.panel.title
  value: Поиск пользователей
  interpolations: 
  locale: ru
  is_proc: false

【讨论】:

  • 问题在于 Locale 记录的 id 值与 fixtures yml 文件中的值相同,而翻译的 locale_ids 会改变它们的值。因此,在从 yml 固定装置加载后应该属于 Translation.find(16) 的所有翻译不属于任何现有的语言环境,而是不属于不存在的 Locale.find(1019186233)。为什么?
  • 我觉得我没有得到你的解释,就像我错过了一些非常基本的东西
  • @zuba 您是否尝试从语言环境和固定装置中的翻译中删除 id ?
  • 我为迟到的回答道歉,Baldrick。我试图从 yaml 夹具文件中删除 Locale.id、Translation.id 和 Translation.locale_id。加载后,Translation.location_id 具有所有记录的保存值,但该值与任何区域设置 ID 都不匹配。同样出于某种原因,Translation.locale 为零,尽管在 yaml 文件中它是“ru”。我想这是因为 Fixture 将名为 locale 的属性识别为对它预期命名为 ru 的某个 Locale 记录的命名引用。
猜你喜欢
  • 2015-11-08
  • 1970-01-01
  • 2015-01-01
  • 2015-03-14
  • 1970-01-01
  • 2019-11-07
  • 2011-01-29
  • 2019-10-23
  • 1970-01-01
相关资源
最近更新 更多