How to write a migration to convert an already-present association to optional?

后端 未结 1 1700
说谎
说谎 2020-12-20 03:44

I have a few belongs_to migrations created&migrated but I see now that in Rails 5, the default behavior is required: true which I do not want.<

相关标签:
1条回答
  • 2020-12-20 04:18

    You can use the change_column_null method for that:

    def change
      change_column_null :table, :column, true
    end
    

    change_column_null is reversible, if you need to rollback the value will be false (or true depending on the case).


    Answering to your question If I simply add optional: true in the model, will it work?. No, if you have a foreign key with nullable value NOT NULL you're going to face an error everytime you try to create a record without that value, e.g:

    A table comments with a relationship to users:

                                                                  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_03de2dc08c" FOREIGN KEY (user_id) REFERENCES users(id)
    

    When you instantiate a new record, Rails will tell nothing about the missing foreign key:

    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
    

    But if you try to persist the record, you're going to get an ActiveRecord::NotNullViolation error because of the not-null constraint.

    0 讨论(0)
提交回复
热议问题