Ошибка RSpec + factory_girl + Globalize?

У меня возникла неприятная проблема с использованием Globalize + RSpec + factory_girl. У меня есть модель с переведенным атрибутом, и при создании фабрик с помощью factory_girl возникает проблема. Код прекрасно это объясняет:

Миграция перевода:

  def self.up
    CandidateBranch.create_translation_table!({
      name: {type: :string, null: false, limit: 150 }
    }, {
      migrate_data: true
    })
  end

Модель:

class CandidateBranch < ActiveRecord::Base
  translates :name
  ####### Validations ---------------------------------------------------------
  validates :name, presence: true, length: { in: 2..150 }

  ####### more code
end

Фабрика:

FactoryGirl.define do
  factory :candidate_branch do
    sequence(:id) { |id| id }
    sequence(:name) { “trying out" }
  end
end

Контрольная работа:

require 'rails_helper'
RSpec.describe CandidateBranch, type: :model do
  context "Validate" do
    it "has a valid factory" do
      record = FactoryGirl.attributes_for(:candidate_branch)
      puts "parameters => #{record.inspect}"
      record = CandidateBranch.create record
      puts "parameters => #{record.inspect}"
      expect(record).to be_valid
    end
  end
end

Журналы:

▶ RAILS_ENV=test bundle exec rspec spec/models/candidate_branch_spec.rb
"parameters => {:id=>1, :name=>\"trying out\"}"
F

Failures:

  1) CandidateBranch Validate has a valid factory
     Failure/Error: record CandidateBranch.create record
     ActiveRecord::StatementInvalid:
       Mysql2::Error: Field 'name' doesn't have a default value: INSERT INTO `candidate_branches` (`id`, `created_at`, `updated_at`) VALUES (1, '2015-02-18 12:27:57.486623', '2015-02-18 12:27:57.486623’)

Mysql-транзакция:

   (0.3ms)  BEGIN
  CandidateBranch::Translation Load (0.5ms)  SELECT `candidate_branch_translations`.* FROM `candidate_branch_translations` WHERE `candidate_branch_translations`.`candidate_branch_id` = 1
   (0.4ms)  SAVEPOINT active_record_1
  SQL (0.6ms)  INSERT INTO `candidate_branches` (`id`, `created_at`, `updated_at`) VALUES (1, '2015-02-18 12:27:57.486623', '2015-02-18 12:27:57.486623')
Mysql2::Error: Field 'name' doesn't have a default value: INSERT INTO `candidate_branches` (`id`, `created_at`, `updated_at`) VALUES (1, '2015-02-18 12:27:57.486623', '2015-02-18 12:27:57.486623')
   (0.2ms)  ROLLBACK TO SAVEPOINT active_record_1
   (0.3ms)  ROLLBACK

Как видно из записи, хотя среди параметров определяется атрибут name при создании записи в запросе к базе данных, таблица перевода явно ничего не находит, а затем пытается создать реестр без переведенного поля, что не удается.

Однако, если мы прокомментируем оператор перевода в модели…

class CandidateBranch < ActiveRecord::Base
  #translates :name
  ####### Validations ---------------------------------------------------------
  validates :name, presence: true, length: { in: 2..150 }

  ####### more code
end


▶ RAILS_ENV=test bundle exec rspec spec/models/candidate_branch_spec.rb
"parameters => {:id=>1, :name=>\"trying out\"}"
"parameters => #<CandidateBranch id: 1, name: \"trying out\", created_at: \"2015-02-18 12:29:09\", updated_at: \"2015-02-18 12:29:09\”>"

MySQL-транзакция:

   (0.3ms)  BEGIN
   (0.4ms)  SAVEPOINT active_record_1
  SQL (0.5ms)  INSERT INTO `candidate_branches` (`id`, `name`, `created_at`, `updated_at`) VALUES (1, 'trying out', '2015-02-18 12:29:09.195756', '2015-02-18 12:29:09.195756')
   (0.3ms)  RELEASE SAVEPOINT active_record_1
   (0.4ms)  ROLLBACK

Это ошибка? Я делаю что-то неправильно? Случалось ли это с кем-то еще?


person José Antonio Yáñez Jiménez    schedule 18.02.2015    source источник


Ответы (2)


Я отвечаю себе. Globalize не заполняет переведенные поля в базовой модели таблицы, а перемещает эти поля в их переводы таблицы. Это означает, что проверка атрибута должна применяться к переведенным полям, поскольку исходное поле пусто.

person José Antonio Yáñez Jiménez    schedule 19.02.2015
comment
Не могли бы вы поподробнее описать этот вопрос. Не понял вашего ответа. - person MZaragoza; 05.05.2015

Как вы сами выяснили, globalize перемещает переведенные значения в таблицу ..._translations.
Ваше сообщение об ошибке вызвано ограничением базы данных NOT NULL для базовой таблицы, которое, очевидно, было установлено предыдущей миграцией с параметром null: false.

Чтобы ваш пример работал, вам нужно добавить в миграцию:

change_column_null :candidate_branches, :name, true
person Martin M    schedule 22.02.2016