2012-01-30 6 views
1

Rubyの検証に苦労しています:私のRailsアプリケーションでは確認=>真です。次のコードを考えてみましょう:レール・サーバーの原因から手動が何かを確認します:確認=> trueとattr_accessorの混乱

1.9.3-p0 :002 > l2 = Thing.create! :pin => 1234567, :pin_confirmation => 1111111 
ActiveRecord::RecordInvalid: Validation failed: Pin doesn't match confirmation 
    .... 
1.9.3-p0 :003 > l2 = Thing.create! :pin => 1234567, :pin_confirmation => 1234567 
=> #<Thing id: 2, pin: 1234567, created_at: "2012-01-30 22:03:29", updated_at: "2012-01-30 22:03:29"> 

が、RSpecの通過の両方をテストして:上記のコードはあるので

# == Schema Information 
# 
# Table name: things 
# 
# id   :integer   not null, primary key 
# pin   :integer(8) 
# created_at :datetime 
# updated_at :datetime 
# 

class Things < ActiveRecord::Base 
    #attr_accessor :pin 
    attr_accessible :pin, :pin_confirmation 


    validates :pin, 
      :confirmation => true, 
      :length => { :within => 7..15 }, 
      :numericality => { :only_integer => true } 

エンド

を、私の検証は、Railsのコンソールから正常に動作します妥当性検査が失敗すると、彼らは彼らがうまくいったときに一致しないと言っています。 :pinのattr_accessorのコメントを外すと、バリデーションは成功しますが、:ピンはデータベースに書き込まれません。

私は、明らかに重要なことを忘れています。ちょうどレンガの壁に流れ込んでいます。

+0

文字列? –

+0

私はあなたが賞を勝ち取ったと思う...コンソールで文字列としてパラメータを実行すると(:pin => "1234567")、同じ検証エラーが発生しました...その次は苦労する必要があります。 – Jeff

答えて

1

上記のFrederickのように、問題はStringのインスタンスをIntegerのインスタンスと比較することです。

可能性よりも、ここでは、あなたのコントローラを持っているものです。

Thing.new(params[:thing]) # note all these params come in as a string 

何が起こっていることは#pinが整数列であることから、次の動作を取得するということです。

my_thing = Thing.new 
my_thing.pin = "123456" 
my_thing.pin # Will be the integer 123456, the attribute has been auto-cast for you 

しかし、 #pin_confirmedは整数列ではなく通常の属性なので、表示される奇妙さは次のとおりです。

my_thing = Thing.new 
my_thing.pin_confirmation = "123456" 
my_thing.pin_confirmation # Will be the *string* "123456", the attribute has been set as is 

そのような場合、自然にどのような値を持っていても、「params」ハッシュ(常に文字列の集合)を介して入力されるため、両方の属性に文字列値を割り当てることになりますが、異なるタイプにキャストすること。

これを解決するにはいくつかの方法があります。

1つでは、#pin_confirmationをデータベースの整数列として作成できます。

他では、次の形式の#pin_confirmationの属性セッターを追加することができます:整数と比較されて

def pin_confirmation=(val) 
    @pin_confirmation = val.to_i 
end 
関連する問題