2016-10-10 39 views
2

我最近將我的Rails 4.2應用程序從ruby 2.0.0切換到2.3.0,當我啓動我的rails服務器($ rails s)時,新notifcation剛剛出現切換到Ruby 2.3.0(2.0.0)創建Active Record驗證問題

/home/app/models/user.rb:127: warning: key :numericality is duplicated and overwritten on line 128 
/homeapp/models/user.rb:127: warning: key :on is duplicated and overwritten on line 128 
/home/app/admin/user.rb:142: warning: key :collection is duplicated and overwritten on line 147 
/home/app/models/deal.rb:223: warning: key :numericality is duplicated and overwritten on line 226 
/home/app/models/deal.rb:234: warning: key :numericality is duplicated and overwritten on line 237 

這是導致問題的行的例子,他們在哪裏上創建帳戶的我設定的屬性nb設置等於3的那些(上:創建),並且用戶在他的賬戶生活中,可以增加他的許多權限,但永遠不能超過7(在:更新)。

validates :nb_of_permissions, 
      presence:true, 
      numericality: { equal_to: 3 }, on: :create,    
      numericality: { less_than_or_equal_to: 7 }, on: :update 

我應該改變什麼?

感謝

+2

問題/錯誤是永遠存在的。只是現在你可以看到它。 :) –

+0

我有這種感覺:)謝謝Rails /紅寶石強大的約定和通知:) – Mathieu

回答

3

這裏的主要區別是,Ruby的升級是告訴你有關 之前未被注意的應用程序中的錯誤。只有第二個numericality: { less_than_or_equal_to: 7 }, on: :update曾經真的被使用過。

irb(main):001:0> { foo: 1, foo: 2 } 
(irb):1: warning: key :foo is duplicated and overwritten on line 1 
=> {:foo=>2} 

當你有相對簡單的條件時使用validates :att, {}。 由於您的驗證適用於不同的生命週期事件,因此您應該將其聲明爲單獨的驗證。

validates :nb_of_permissions, { presence: true } 
validates_numericality_of :nb_of_permissions equal_to: 3, on: :create 
validates_numericality_of :nb_of_permissions less_than_or_equal_to: 7, on: :update 

測試模型驗證的基礎骨頭實際上是很容易(雖然不是光滑與早該-匹配器):

RSpec.describe Thing do 
    describe "validations" 
    describe "#nb_of_permissions" do 
     context "when updating" do 
     let(:thing) { Thing.create(nb_of_permissions: 3) } 
     let(:errors) { thing.valid?.errors[:nb_of_permissions] } 
     it 'is must be present' do 
      thing.nb_of_permissions = nil 
      expect(errors).to include 'must be present.' 
     end 
     it 'is must be at least 7' do 
      thing.nb_of_permissions = 10000 
      expect(errors).to include "must be less than or equal to 7" 
     end 
     end 
    end 
    end 
end 
+0

PS。如果你的應用很重要,那麼你應該在某處確實進行測試,以確保兩種驗證都適用於'nb_of_permissions'。 – max

+0

已經有測試:)感謝您的幫助, – Mathieu

+2

@Mathieu:猜你的測試沒有完全測試任何東西:) –

3

你應該試試這個

validates :nb_of_permissions, presence:true, numericality: { equal_to: 3 }, on: :create 
validates :nb_of_permissions, presence:true, numericality: { less_than_or_equal_to: 7 }, on: :update 
+0

很酷的工作。只是一個腐蝕問題:那麼如果在創建我有存在:真,如果意味着更新它,如果當然已經存在,然後可能在更新的第二條建議線上,我不需要再次驗證存在=真? – Mathieu

+1

不,您要麼在我的回答中分開存在和數字驗證,要麼爲兩者添加存在驗證。如果你在第二行刪除'presence:true',由於'validates_numericality_of'的工作方式,它會讓'nb_of_permissions'的nil值更新。 – max

+1

如果需要存在,您需要測試存在。畢竟在調用update之前,nb_of_permissions可能會被設置爲null。 – David

3

您的舊代碼是越野車,而不是做你認爲它是。這裏的行爲沒有變化;你只是被顯示一個有用的警告,以突出可能的錯誤!

考慮以下簡單的例子:

hash = {a: 1, a: 2} 

在Ruby版本2.0 2.3,這僅相當於定義:

hash = {a: 2} 

...由於哈希鍵被覆蓋。同樣的,你的代碼:

validates :nb_of_permissions, 
      presence:true, 
      numericality: { equal_to: 3 }, on: :create, 
      numericality: { less_than_or_equal_to: 7 }, on: :update 

...是,始終是,相當於只是寫:

validates :nb_of_permissions, 
      presence:true, 
      numericality: { less_than_or_equal_to: 7 }, 
      on: :update 

There is more than one way to do it,但例如,你可以通過定義驗證修復這個bug,如:

validates :nb_of_permissions, 
      presence:true, 
      numericality: { less_than_or_equal_to: 7 }, 
      on: :update 

validates :nb_of_permissions, 
      presence:true, 
      numericality: { equal_to: 3 }, 
      on: :create