2012-03-17 13 views
7

Rails(3.2.0)でRuby(1.9.3)を実行していて、仮想属性の検証に問題があります。Ruby on Railsの仮想属性の検証

私はFlightというモデルを持っています。とりわけ、出発空港と到着空港を表す属性を持つ航空便を表しています。

空港を選択するためのselectが潜在的に巨大であるため、私は完全にうまく動作しているオートコンプリートソリューションを選択しました。私は適切に空港の実際のIDを移入するbefore_validationコールバックを使用しています:

before_validation do 
    self.departure_airport = Airport.find_by_long_name(departure_airport_name) 
    self.arrival_airport = Airport.find_by_long_name(arrival_airport_name) 
end 

問題はコミットが失敗し、ユーザーがデータベースに存在しない空港の名前を入力したときにすることを、しかし、ですいずれかの空港のIDがnilであるためです。すばらしいです。何ていない偉大な、しかし、技術的に、それは別のフィールドへの入力ですので、この検証エラーがフォームに反映されていないということです。

validates :departure_airport, :arrival_airport presence: true 

attr_accessor :departure_airport_name, :arrival_airport_name 

<%= f.input :departure_airport_name %> 
<%= f.input :arrival_airport_name %> 

が適切について行くにはこれさえ方法ですが、空港の名前を変換し、 before_validationコールバックのIDに変換しますか?もしそうなら、検証エラーを空港の仮想名属性に表示させるにはどうすればよいですか?

答えて

4

私はbefore_validationコールバックで正しい方法を行っていると思います。

通常の属性のように仮想属性を検証できます。だから、あなたが必要とするのは、モデルの検証だけです。これを試してみてください:

validates :departure_airport, presence: true 
validates :arrival_airport, presence: true 

これはオブジェクトエラーにエラーを追加する必要がありますし、エラーがフォームに表示されなければならない...迅速な対応のための

+0

ありがとう!私はすでに 'departure_airport'と' arrival_airport'のバリデーションを持っています。問題は、これらがフォーム上の 'input'が表すフィールドではないということです。誰かがそこにテキストを入力すると、フィールドは存在しますが、実際の 'Airport'オブジェクトは失われてしまうので、単にプレゼンスを検証することはできません。 – Laurens

+0

なぜ 'before_validation'コールバックを登録するのですか?ユーザーが不器用になると、空港が見つからず、検証が失敗します。エラーが追加され、ユーザーに表示されます。たぶんあなたは、カスタムエラーマッサージを追加することを検討する必要があります。 – klump

+0

申し訳ありませんが悪いです。よくわからなかった。おそらく、独自の検証方法が必要です。 'self.errors.add(:fieldname、" message ")'でオブジェクトにエラーを追加することができます。 'departure_airport_name'をフィールド名として使用し、メッセージを追加すると、それは' departure_airport_name'フィールドに表示されます。 – klump