简体   繁体   中英

Why Rails data loaded from Fixtures are broken?

I got two fixture files for Locales and Translations. Locales are loaded fine, but Translations are broken:

Fixture

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

Becomes the record:

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

For some reason locale instead of 'ru' becomes nil, while locale_ib instead of 16 becomes 1019186233 for every fixture in a file.

I load fixtures such way:

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)

Translation model

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

The migration

  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

I see in a test.log that inserts to DB contain broken data. When I load the fixture file in rails concole with YAML.load_file 'test/fixtures/translations.yml' I get correct Hash data.

Why that happens? How to fix that? Rails-2.3.8 , PostgreSql-8.4


UPDATE: Tried named fixtures. In locales.yml:

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

and in translations.yml all locale key values set to locale_00016

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

YES, that works!

Translation id referred to existing and correct Locale record, but locale was still nil, to fix it I ran Locale.find_by_code('ru').translations.update_all(:locale => 'ru')

If locale_id is set, it seems ok; locale will be filled by Rails when you need it (the first time you will request it). 1019186233 is the id generated by rais when the fixtures are created.

Most of the time, you do not need to specify ids in fixtures, rails generate them for you, so fixtures like below should be fine (you should not define both locale and locale_id in the Translation fixture):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM