gpt4 book ai didi

ruby-on-rails - Rails 5 更新枚举不更新

转载 作者:行者123 更新时间:2023-12-02 19:42:34 25 4
gpt4 key购买 nike

在 Rails 和 ActiveRecord 中,我正在为模型中的 enum 行为而苦苦挣扎。首先,我在 AR 迁移中在数据库级别设置的 default 在我运行测试时没有生效,其次,我根本无法更新它。这是一些代码,为简洁起见进行了简化。

在我的模型中,枚举声明如下:

class MyModel < ApplicationRecord
# as you can see this is a join table for different_model and another_model
belongs_to :different_model
belongs_to :another_model

enum blocked: %w[no yes] # also tried with symbols, like: %i[no yes]
end

迁移如下:

class AddBlockedToMyModel < ActiveRecord::Migration[5.2]
def change
add_column :my_models, :blocked, :integer, default: 0
end
end

我使用以下方法创建对象:

my_model = MyModel.where(different_model: @different_model, another_model: @another_model).first_or_create

这行得通,我使用 byebug 来检查这条记录是否持久存在(因此也是有效的)

然后尝试更新枚举 blocked :

my_model.update(blocked: 'yes')

但是 blocked 属性保持为 nil

我重构了,尝试使用:

my_model.blocked = 'yes'
my_model.save

并将 byebug 卡在中间,看看它是否无效,但事实并非如此。 .valid? 在将 blocked 更改为 'yes' 后返回 true,所以我也尝试将其更改为整数1,保存后还是返回nil

此问题仅在运行测试时发生。当在 rails console 中运行时,一切都如我所料 - 数据库级别的 default 接管并使用 blocked: 'no' 实例化模型它也可以通过任何常规 AR 方式进行更新,只是不在测试中。我是否在这里遗漏了一些非常明显的东西,或者是我没有得到的 enum 的一些奇怪的副作用?

DB 是 Postgres,以防万一。

最佳答案

1) 尽量避免将 yesno 作为枚举值。 Rails 将为每个值创建方法,例如 #yes?#no!,以防您需要为不同的字段添加另一个 yes/no 枚举,它可能不会像您预期的那样工作。

最好这样定义

enum status: [:released, :blocked]

或者我实际上更喜欢哈希表示来明确存储什么数据库值:

enum status: {
released: 0,
blocked: 1
}

然后,不要调用 update!,只需调用

your_instance.blocked!

它会做这件事。

2) 作为一般建议,在数据库中使该字段不可为空(因为我假设您此时不希望该字段具有三种状态):

change_column_null :table_name, :column_name, true

关于ruby-on-rails - Rails 5 更新枚举不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59896594/

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