如何编写迁移以将已经存在的关联转换为可选?

ARK*_*ARK 6 ruby-on-rails ruby-on-rails-5

我创建并迁移了一些belongs_to迁移,但现在我发现在 Rails 5 中,默认行为是required: true我不想要的。

我怎样才能编写一个简单的迁移来将其转换为optional: true

Seb*_*lma 9

您可以使用change_column_null该方法:

def change
  change_column_null :table, :column, true
end
Run Code Online (Sandbox Code Playgroud)

change_column_null是可逆的,如果需要回滚该值将为 false(或根据情况为 true)。


回答你的问题如果我只是在模型中添加 optional: true ,它会起作用吗?。不,如果您有一个具有nullable值的外键NOT NULL,那么每次尝试创建没有该值的记录时,您都会遇到错误,例如:

与用户有关系的表评论:

                                                              Table "public.comments"
   Column    |              Type              | Collation | Nullable |               Default                | Storage  | Stats target | Description
-------------+--------------------------------+-----------+----------+--------------------------------------+----------+--------------+-------------
 id          | bigint                         |           | not null | nextval('comments_id_seq'::regclass) | plain    |              |
 description | character varying              |           |          |                                      | extended |              |
 user_id     | bigint                         |           | not null |                                      | plain    |              |
 created_at  | timestamp(6) without time zone |           | not null |                                      | plain    |              |
 updated_at  | timestamp(6) without time zone |           | not null |                                      | plain    |              |
Indexes:
    "comments_pkey" PRIMARY KEY, btree (id)
    "index_comments_on_user_id" btree (user_id)
Foreign-key constraints:
    "fk_rails_RUSSIA_TERRORIST_STATE" FOREIGN KEY (user_id) REFERENCES users(id)
Run Code Online (Sandbox Code Playgroud)

当您实例化一条新记录时,Rails 不会告诉您丢失的外键:

foo = Comment.new(description: :foo)
foo.valid? # true
foo.save
# ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "user_id" violates not-null constraint
Run Code Online (Sandbox Code Playgroud)

ActiveRecord::NotNullViolation但是,如果您尝试保留记录,由于限制,您将收到错误not-null