Rails 4,RSpec,MySQL2默认值错误仅在第一工厂 [英] Rails 4, RSpec, MySQL2 default value error on first factory only

查看:63
本文介绍了Rails 4,RSpec,MySQL2默认值错误仅在第一工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Rails 3.2.14升级到Rails4.在Rails 3分支的测试套件上运行RSpec时,所有测试均通过.但是,在Rails 4分支上,我仅在创建工厂的 first 实例上遇到错误.该错误显示为:

ActiveRecord::StatementInvalid:
   Mysql2::Error: Field 'id' doesn't have a default value: INSERT INTO `of_of_measurements` (`aerobic_steps`, `calories`, `date`, `device_serial`, `distance`, `is_device_input`, `server_time`, `total_steps`, `user_id`) VALUES (15, 20, '2013-09-11 16:57:36', 'HJ1', 25.0, 0, '2013-09-11 16:57:36', 10, 1)

我的工厂是这样的:

factory :upload do
  sequence(:id) { |n| n }
  date Time.zone.now
  total_steps 100
  aerobic_steps 75
  distance 500.0
  calories 50
  sequence(:device_serial) { |n| "HJ#{n}" }
  is_device_input 0
  server_time Time.now
  person
end

我知道将id显式添加到工厂通常不是很好,但是鉴于我正在使用的一些遗留数据库问题需要一些奇怪的关联,因此在这里我发现这是不可避免的.

完整的测试套件包括几个需要创建上载工厂的测试,而真正令我困惑的是,所有其他涉及上载工厂的测试均成功通过.我非常确定问题不在于任何特定的测试,因为RSpec随机化了测试的运行顺序,因此一次尝试失败的测试将通过下一次(当它稍后出现在测试套件中时). /p>

我还有其他一些工厂正在执行相同的sequence(:id) { |n| n }代码,但这些工厂都没有这个问题.我还检查了MySQL中的describe [table_name];,所有表的id字段看起来都相同:默认为NULL,自动递增.

更新 这是来自模式转储的of_of_measurements表配置:

-- Table structure for table `of_of_measurements`
--

DROP TABLE IF EXISTS `of_of_measurements`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `of_of_measurements` (
  `id` bigint(20) NOT NULL,
  `user_id` bigint(20) NOT NULL,
  `date` datetime NOT NULL,
  `total_steps` int(11) NOT NULL,
  `aerobic_steps` int(11) NOT NULL DEFAULT '0',
  `aerobic_walking_time` int(11) DEFAULT NULL,
  `calories` int(11) DEFAULT NULL,
  `distance` float DEFAULT NULL,
  `fat_burned` float DEFAULT NULL,
  `hourly_steps` text COLLATE utf8_unicode_ci,
  `hourly_aerobic_steps` text COLLATE utf8_unicode_ci,
  `hourly_equip` text COLLATE utf8_unicode_ci,
  `hourly_event` text COLLATE utf8_unicode_ci,
  `is_device_input` tinyint(4) NOT NULL,
  `day_serial` int(11) DEFAULT NULL,
  `server_time` datetime NOT NULL,
  `device_serial` text COLLATE utf8_unicode_ci,
  `weight` float DEFAULT NULL,
  `clientversion` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `platform` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `hrm_duration` int(11) DEFAULT NULL,
  `hrm_max_hr` int(11) DEFAULT NULL,
  `hrm_avg_hr` int(11) DEFAULT NULL,
  `hrm_status` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
  `hrm_distance_readings` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
  `hrm_hr_readings` varchar(1024) COLLATE utf8_unicode_ci DEFAULT NULL,
  `walkMass` float DEFAULT NULL,
  `aerobicMass` float DEFAULT NULL,
  `aerobicCalories` int(11) DEFAULT NULL,
  `basalMetabolism` int(11) DEFAULT NULL,
  `walkCalories` int(11) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `unique_measure` (`date`,`device_serial`(20),`user_id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

解决方案

我找到了此问题的答案.旧版数据库未将id字段设置为自动递增.结果,database_cleaner在清理测试套件数据库时遇到了麻烦.解决方案是将self.primary_key = 'id'添加到我的上传模型中.

I'm upgrading from Rails 3.2.14 to Rails 4. When running RSpec on my test suite in my Rails 3 branch, all tests pass. On the Rails 4 branch, however, I'm getting an error on the first instance only of creating a factory. The error reads:

ActiveRecord::StatementInvalid:
   Mysql2::Error: Field 'id' doesn't have a default value: INSERT INTO `of_of_measurements` (`aerobic_steps`, `calories`, `date`, `device_serial`, `distance`, `is_device_input`, `server_time`, `total_steps`, `user_id`) VALUES (15, 20, '2013-09-11 16:57:36', 'HJ1', 25.0, 0, '2013-09-11 16:57:36', 10, 1)

My factory looks like this:

factory :upload do
  sequence(:id) { |n| n }
  date Time.zone.now
  total_steps 100
  aerobic_steps 75
  distance 500.0
  calories 50
  sequence(:device_serial) { |n| "HJ#{n}" }
  is_device_input 0
  server_time Time.now
  person
end

I know it's generally not great to explicitly add id to factories, but given some legacy database issues I'm working with that require some bizarre associations, I've found it unavoidable here.

The full test suite includes several tests that require creating an upload factory, and what's really confusing me is that all other tests involving upload factories pass successfully. I'm pretty sure the issue is not with any specific test, because RSpec randomizes the order of the tests run and so a test that fails in one attempt will pass in the next (when it shows up later in the test suite).

I have a few other factories in which I'm doing the same sequence(:id) { |n| n } code, and none of them have this problem. I've also checked describe [table_name]; in MySQL and the id fields for all tables look the same: Default NULL, auto-increment.

Update Here's the of_of_measurements table configuration from a schema dump:

-- Table structure for table `of_of_measurements`
--

DROP TABLE IF EXISTS `of_of_measurements`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `of_of_measurements` (
  `id` bigint(20) NOT NULL,
  `user_id` bigint(20) NOT NULL,
  `date` datetime NOT NULL,
  `total_steps` int(11) NOT NULL,
  `aerobic_steps` int(11) NOT NULL DEFAULT '0',
  `aerobic_walking_time` int(11) DEFAULT NULL,
  `calories` int(11) DEFAULT NULL,
  `distance` float DEFAULT NULL,
  `fat_burned` float DEFAULT NULL,
  `hourly_steps` text COLLATE utf8_unicode_ci,
  `hourly_aerobic_steps` text COLLATE utf8_unicode_ci,
  `hourly_equip` text COLLATE utf8_unicode_ci,
  `hourly_event` text COLLATE utf8_unicode_ci,
  `is_device_input` tinyint(4) NOT NULL,
  `day_serial` int(11) DEFAULT NULL,
  `server_time` datetime NOT NULL,
  `device_serial` text COLLATE utf8_unicode_ci,
  `weight` float DEFAULT NULL,
  `clientversion` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `platform` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `hrm_duration` int(11) DEFAULT NULL,
  `hrm_max_hr` int(11) DEFAULT NULL,
  `hrm_avg_hr` int(11) DEFAULT NULL,
  `hrm_status` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
  `hrm_distance_readings` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
  `hrm_hr_readings` varchar(1024) COLLATE utf8_unicode_ci DEFAULT NULL,
  `walkMass` float DEFAULT NULL,
  `aerobicMass` float DEFAULT NULL,
  `aerobicCalories` int(11) DEFAULT NULL,
  `basalMetabolism` int(11) DEFAULT NULL,
  `walkCalories` int(11) DEFAULT NULL,
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `unique_measure` (`date`,`device_serial`(20),`user_id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

解决方案

I found the answer to this issue. The legacy database did not set the id field to auto-increment. As a result, database_cleaner was having trouble cleaning the test suite db. The solution was to add self.primary_key = 'id' to my Upload model.

这篇关于Rails 4,RSpec,MySQL2默认值错误仅在第一工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆