I was wondering what are the effects and the things to consider when you update an enum definition in your model? Or if this something that you should avoid to do? What if I already have a million record on the table and want to change the definition from this to this.
class Post < ApplicationRecord
enum :status, { published: 0, draft: 1, archived: 2 }
end
class Post < ApplicationRecord
enum :status, { published: 0, draft: 1, edited: 2, deleted: 3 }
end
More generally, what should be considered when adding and deleting columns from a table?
CodePudding user response:
Enum will not add a new columm in the table. It will just have different values in the same column. For example, from you new definition, the archived posts are now edited posts and there will be new deleted posts too. In the database level, now it will have three distinct values - 0,1,2,3 in the same column.
The other advantage of enum is that Rails will provide some helpful helpers to work with them.
CodePudding user response:
The enum doesn't add new columns on the table, it represents a possible value to a column.
If initially the enum is { published: 0, draft: 1, archived: 2 }
and it eventually changes to { published: 0, draft: 1, edited: 2, deleted: 3 }
, it should be a big problem, because you changed the value reference.
For example, if at first you had a Post
archived post (means the status
value in the database is 2, according to the enum) and it is now edited, it will happen the following thing:
Old:
@post.status #=> 'archived'
@post.archived? #=> true
New (and I mean with no updates to the database. It will happen if you just change the enum in the model in the example you gave):
@post.status #=> 'edited'
@post.archived? #=> false
@post.edited? #=> true
It changed the value, because the column data (2) represents a value that is no longer what you had initially (:archived => 2
).
When working with enums, you should always add different values in the enum definition, so it represents different things.
In your example, I feel it could be:
enum :status, { published: 0, draft: 1, edited: 3, deleted: 4 }
, so it doesn't reference the old value (:archived => 2
).
In this way, you have different references, and it also won't break it you want to add the archived back in a near future:
enum :status, { published: 0, draft: 1, archived: 2, edited: 3, deleted: 4 }