2015-11-04 81 views
0

使用Rails 4.2.1。我有一個字段是一個枚舉的模型:validates_presence_of失敗並返回枚舉

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! 

產生相同的結果。

這是否意味着validates_presence_of不能與枚舉一起使用?如果確實如此,那麼根本原因是什麼?

回答

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。

+0

非常奇怪,已經案例2失敗,我的驗證錯誤。也許這是4.2.1中的一個bug已被修復? – p4sh4

+0

我也測試了這個4.2.4並取得了和你一樣的結果。 – p4sh4

+0

這不是一個錯誤,我找到了問題,請看我的答案。謝謝您的幫助! – p4sh4