2

我在使用 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”,但翻译表显然什么也没找到,然后尝试在没有翻译字段的情况下创建注册表,但失败了。

但是,如果我们在模型中注释翻译语句……</p>

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\”&gt;"

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

它是一个错误吗?难道我做错了什么?这发生在其他人身上吗?

4

2 回答 2

0

我自己回答。Globalize 不会填充表基础模型中的已翻译字段,它所做的是将这些字段移动到它们的表翻译中。这意味着必须对已翻译的字段应用属性验证,因为原始字段为空。

于 2015-02-19T10:17:57.597 回答
0

正如您自己发现的那样, globalize 将翻译后的值移动到 ..._translations 表中。
您的错误消息是由NOT NULL基表上的数据库约束引起的,这显然是由以前的迁移设置的 option null: false

为了使您的示例工作,您需要添加到您的迁移:

change_column_null :candidate_branches, :name, true
于 2016-02-22T10:11:31.500 回答