Rails迁移不会创建NOT NULL约束

时间:2015-07-02 21:11:06

标签: ruby-on-rails rails-migrations

我为我的Rails 3.2插件进行了这次数据库迁移:

class CreateIssueChangeApprovements < ActiveRecord::Migration
  def change
    create_table :issue_change_approvements do |t|
      t.timestamps
      t.references :issue, :null => false
      t.references :user, :null => false
      t.string :field_type, :limit => 30
      t.string :old_value
      t.string :value
      t.integer :approved_by_id
      t.boolean :is_closed, :default => 0
      t.string :status, :default => '', :limit => 30
    end
    add_index :issue_change_approvements, :issue_id
    add_index :issue_change_approvements, :user_id
  end
end

一旦我针对MySQL数据库运行它,我在issue_iduser_id字段上看不到NOT NULL约束,也没有外键。

谁能告诉我这是怎么回事?

UPD:

这里奇怪的是,当我去MySQL Workbench并为我新创建的表生成一个脚本时,我得到了这个:

CREATE TABLE `issue_change_approvements` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `issue_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `field_type` varchar(30) DEFAULT NULL,
  `old_value` varchar(255) DEFAULT NULL,
  `value` varchar(255) DEFAULT NULL,
  `approved_by_id` int(11) DEFAULT NULL,
  `is_closed` tinyint(1) DEFAULT '0',
  `status` varchar(30) DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `index_issue_change_approvements_on_issue_id` (`issue_id`),
  KEY `index_issue_change_approvements_on_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

然而,当我运行这样的声明时:

insert into issue_change_approvements(value) values('hello')

它成功执行并添加了一个包含大量NULL值的行。

UPD 2: 这是describe issue_change_approvements显示的内容:

+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| created_at     | datetime     | NO   |     | NULL    |                |
| updated_at     | datetime     | NO   |     | NULL    |                |
| issue_id       | int(11)      | NO   | MUL | NULL    |                |
| user_id        | int(11)      | NO   | MUL | NULL    |                |
| field_type     | varchar(30)  | YES  |     | NULL    |                |
| old_value      | varchar(255) | YES  |     | NULL    |                |
| value          | varchar(255) | YES  |     | NULL    |                |
| approved_by_id | int(11)      | YES  |     | NULL    |                |
| is_closed      | tinyint(1)   | YES  |     | 0       |                |
| status         | varchar(30)  | YES  |     |         |                |
+----------------+--------------+------+-----+---------+----------------+

1 个答案:

答案 0 :(得分:1)

默认情况下,Rails不会创建任何约束。 null: false选项将不允许此sql字段的空值,但它不会添加约束。 您只需在模型关系中设置所需的选项,而不是rails中的foreign_key约束,例如has_many :issues, dependent: :destroy 我想这个策略是为了更快的架构迁移而选择的,停机时间更短。

但是,有一个选项可以通过显式指定它们来对数据库级别使用约束。您可以在rails 4.2和rails 4.2之前使用foreigner gem。默认情况下,它们包含dsl。

请参阅 Have Some (Referential) Integrity with Foreign Keys

2.5 Foreign Key Support