validates_presence_of因枚举而失败

时间:2015-11-04 03:45:47

标签: ruby-on-rails validation activerecord enums

使用Rails 4.2.1。我有一个带有枚举字段的模型:

  def create
    user = User.find_by(email: user_params[:email])

    if user && user.authenticate(user_params[:password])
      session[:current_user_id] = user.id
      flash[:message] = "Thanks for loggin in " + user.first_name
    else
      flash[:message] = "Username or Password combo are not correct"
    end
    redirect_to root_path
  end

在控制器中,我试图保存模型:

class MyModel < ActiveRecord::Base
  enum my_enum: { first_value: 0, second_value: 1 }
  validates_presence_of :my_id, :username, :my_enum
end

这给了我my_model = MyModel.find_or_initialize_by(my_id: my_id) my_model.update(username: username, my_enum: :first_value)

在保存之前将所需属性分配给对象,如下所示:

Validation failed: My enum can't be blank

甚至

my_model.username = username
my_model.first_value!

产生相同的结果。

这是否意味着my_model.username = username my_model.my_enum = 0 my_model.save! 不能与枚举一起使用?如果情况确实如此,那么根本原因是什么?

2 个答案:

答案 0 :(得分:2)

这不是错误。问题是my_enum列的类型为string,我试图保存一个整数。替换

enum my_enum: { first_value: 0, second_value: 1 }

enum my_enum: { first_value: '0', second_value: '1' }

修复了问题,更改列也修复了它。

显然,使用字符串作为枚举是/是“秘密的未记录的功能”。有关其他详细信息,请参阅this pull request(在撰写本文时仍然开放)。

答案 1 :(得分:1)

我看到validates_presence_of仍然适用于枚举。这是我的模特

# production.rb
class Production < ActiveRecord::Base
  enum status: {active: 1, deactive: 0}
  validates_presence_of :status
end

我在rails console

上测试了你的案例

案例1:

2.2.0 :001 > Production.create!
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Status can't be blank

案例2:

2.2.0 :001 > prod = Production.find_or_initialize_by(title: "abc")
  Production Load (0.8ms)  SELECT  "productions".* FROM "productions" WHERE "productions"."title" = ? LIMIT 1  [["title", "abc"]]
 => #<Production id: nil, title: "abc", price: nil, description: nil, status: nil, created_at: nil, updated_at: nil>
2.2.0 :002 > prod.update(price: 23, status: :active)
   (0.3ms)  begin transaction
  SQL (0.8ms)  INSERT INTO "productions" ("title", "price", "status", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["title", "abc"], ["price", 23], ["status", 1], ["created_at", "2015-11-04 05:58:43.851364"], ["updated_at", "2015-11-04 05:58:43.851364"]]
   (0.7ms)  commit transaction
 => true

案例3:

2.2.0 :001 > prod = Production.find_or_initialize_by(title: "def")
  Production Load (0.6ms)  SELECT  "productions".* FROM "productions" WHERE "productions"."title" = ? LIMIT 1  [["title", "def"]]
 => #<Production id: nil, title: "def", price: nil, description: nil, status: nil, created_at: nil, updated_at: nil>
2.2.0 :002 > prod.description = "bla"
 => "bla"
2.2.0 :003 > prod.save!
   (0.2ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Status can't be blank

案例4:

2.2.0 :001 > prod = Production.find_or_initialize_by(title: "def")
  Production Load (0.6ms)  SELECT  "productions".* FROM "productions" WHERE "productions"."title" = ? LIMIT 1  [["title", "def"]]
 => #<Production id: nil, title: "def", price: nil, description: nil, status: nil, created_at: nil, updated_at: nil>
2.2.0 :002 > prod.status = 0
 => 0
2.2.0 :003 > prod.save!
   (0.2ms)  begin transaction
  SQL (0.8ms)  INSERT INTO "productions" ("title", "status", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "def"], ["status", 0], ["created_at", "2015-11-04 06:01:16.391026"], ["updated_at", "2015-11-04 06:01:16.391026"]]
   (0.7ms)  commit transaction
 => true

我使用的是Rails 4.2.4。