2016-10-10 8 views
2

私は最近、Ruby 2.0.0から2.3.0に私のRails 4.2アプリケーションを切り替えました。そして、私のレールサーバ($ rails s)ただここで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 

登場新しいnotifcationが問題を引き起こしラインの一例であり、彼らは、アカウントの作成時に、私は(:上:作成)3に等しいNB属性を設定するものであり、かつユーザー彼のアカウントの生活の中で、彼の許可の数を増やすことはできますが、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/ruby​​ :) – Mathieu

答えて

3

:など以前は気付かれていなかったあなたのアプリのバグ。 2番目の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 

テストモデルの検証ベースの骨(Shoulda-マッチャほどツルツルしていないが)実際にはかなり簡単です:

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

@マチュー:あなたのテストでは何もテストしていないと思っています:) –

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

涼しいそれは働いた。もしも私が存在を知っていれば、真実であることを意味していれば、更新時に2番目の提案行に既に存在していれば、存在を真実と再度検証する必要はないでしょうか? – Mathieu

+1

いいえ、私の回答のように存在と数値のバリデーションを分離するか、または両方に存在のバリデーションを追加します。 2行目で 'presence:true'を削除すると' validates_numericality_of'の働きにより 'nb_of_permissions'の値がnilで更新されます。 – max

+1

存在する必要がある場合はプレゼンスをテストする必要があります。すべてのnb_of_permissionsが、updateを呼び出す前に、nullに設定される可能性があります。 – David

3

を試してみてくださいバギーだった、とあなたはそれがだったと思う何をやっていません。ここで行動に変化はありませんでした。あなたは間違いの可能性を強調するための有益な警告を表示しているだけです!ハッシュキーが上書きされますので...

hash = {a: 2} 

:ルビーバージョン2.0 2.3では

hash = {a: 1, 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はなく、例えば、あなたは検証を定義することによって、このバグを修正することができ、ここでの主な違いは、Rubyのアップグレードは についてあなたを語っていることである

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 
関連する問題