gpt4 book ai didi

mysql - Rails 4 备用主键与 MySQL

转载 作者:行者123 更新时间:2023-11-30 23:13:02 25 4
gpt4 key购买 nike

我有一个奇怪的问题,我就是想不通。

我想利用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。

有没有人知道我可以做什么来使我的测试套件在此设置中正常工作?

最佳答案

我想通了。

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

所以虽然我的开发数据库看起来像我预期的那样,但测试数据库看起来不同 - 生成 schema.rb 文件的代码似乎无法理解我创建的数据库格式并且不会创建反射(reflect)我的 schema.rb正确迁移。

如果我加载我的测试数据库:

$ rake db:migrate RAILS_ENV=test

然后运行我的测试套件:

$ rake test:all

一切正常。这是因为 test:all 任务在运行测试套件之前不会重新加载数据库。

所以我在问题中描述的创建替代主键同时保持 Rails ID 键有效,除了 schema.rb 部分。

关于mysql - Rails 4 备用主键与 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19125207/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com