Rails 4与MySQL交替使用主键

时间:2013-10-01 20:23:12

标签: mysql ruby-on-rails ruby

我有一个奇怪的问题,我无法弄清楚。

我想使用mysql的集群功能将相关记录存储在磁盘上。 Mysql集群由表上的主键组成,对于默认的rails模型是ID。

但是,对于很多表,表的主键可能是有意义的,例如,user_id,subscription_id,聚集每个表旁边的相关记录,并在您询问时进行非常有效的查找。所有用户订阅的数据库。

为此,我创建了一个mysql表,如:

 execute('create table subscriptions (
             id         integer not null auto_increment,
             user_id    integer not null,
             feed_id    integer not null,
             folder_id  integer,
             created_at     datetime,
             updated_at     datetime,
             primary key (user_id, feed_id),
             key id (id)
          ) engine=InnoDB default charset=utf8');

请注意,我的PK是user_id,feed_id,但我仍然有ID列,并且我希望rails仍然使用它,因为它认为它是表的PK。

首先,在我设置之前,这根本不起作用:

class Subscription < ActiveRecord::Base

  self.primary_key = 'id'
  ...
end

现在出现了奇怪的部分。

当我运行测试时,我收到一个奇怪的错误:

Mysql::Error: Field 'id' doesn't have a default value: INSERT INTO `subscriptions` 

然而 - 如果我将应用程序放在开发模式并通过网页进行操作,它就可以正常工作。

经过大量的谷歌搜索,我找到了一个猴子补丁来阻止Rails将MySQL设置为更严格的模式:

class ActiveRecord::ConnectionAdapters::MysqlAdapter

private
  alias_method :configure_connection_without_strict_mode, :configure_connection

  def configure_connection
    configure_connection_without_strict_mode
    strict_mode = "SQL_MODE=''"
    execute("SET #{strict_mode}", :skip_logging)
  end
end

如果我添加这个,我的测试套装似乎有效(对于大多数测试,但不是全部),但任何创建的模型的ID都为零。

再次在生产模式下,通过网页工作正常,模型会按预期获得auto_increment ID。

有没有人对我能做什么有任何想法让我的测试套件在这个设置中正常工作?

1 个答案:

答案 0 :(得分:0)

我弄清楚发生了什么。

我不记得的是,开发数据库是通过对数据库运行迁移来创建的,数据库也生成了schema.rb文件。然后使用schema.rb文件加载测试数据库。

因此,虽然我的开发数据库看起来像我预期的那样,但测试数据库看起来与众不同 - 生成schema.rb文件的代码似乎无法理解我创建的数据库格式,也无法创建反映我的架构的.rb正确迁移。

如果我用:

加载我的测试数据库
$ rake db:migrate RAILS_ENV=test

然后运行我的测试套件:

$ rake test:all

事情正常。这是因为测试:所有任务在运行测试套件之前都没有重新加载数据库。

所以我在问题中描述了在保持rails ID键的同时创建备用主键,但schema.rb部分除外。