2011-05-20 23 views
1

オリジナルタイトルの検証に失敗しました。* _attributes =()は、ネストされた属性

ネストされた属性を処理する親クラスです。

meeting.rb

has_many :proposed_times, :dependent => :destroy, :inverse_of => :meeting 
validates_associated :proposed_times 
accepts_nested_attributes_for :proposed_times 
... 
def proposed_times_attributes=(attributes) 
    attributes.each do |key,value| 
    value[:timezone] = timezone 
    if value[:id] 
     p = ProposedTime.find(value[:id]) 
     value.delete(:id) 
     p.update_attributes(value) 
    else 
     self.proposed_times << ProposedTime.new(value) 
    end 
    end 
end 

私が検証しようとしているクラスは以下の通りです。基本的には、日付が将来であることを検証する必要があります。そして私はbefore_validationメソッドで私のstarting_atを構築しています。だから私は、(A)日付を正しく構成できない場合(ユーザーが日付を削除する場合、ユーザーに記入する必要がある場合)(B)それを構築すると、それは保存に失敗し、私は情報を修正するためにそれをビューに戻す方法を知らない。ここで

proposed_times.rb

belongs_to :meeting, :inverse_of => :proposed_times 
validate :future_enough 
before_validation :construct_starting_at 
... 
def future_enough 
    unless starting_at && starting_at >= (Time.now + 15.minutes) 
    errors.add(:not_far_enough_out, "msg not used but: starting_at isn't far enough out") 
    end 
end 

def construct_starting_at 
    if date.present? && time.present? && timezone.present? 
    begin 
     d = Time.parse(date) 
     self.starting_at = Time.zone.parse("#{d.year}-#{d.month}-#{d.day} #{time.hour}:#{time.min}:00 #{timezone}") 
    rescue 
     self.starting_at = nil 
    end 
    end 
end 

は、私が使用している図です。私はこれがこの機能を処理する最善の方法ではないことを知っていますが、私が持っているもので作業しています...私が行うすべてはthank_youにリダイレクトされます。なぜそれがセーブで失敗していないのか分かりません。

meeting_controller.rb

def propose_times 
    @consultation = Consultation.find(params[:id]) 
    @user = current_user 

    # If this is coming second time around with data to save 
    if request.put? 
    @consultation.attributes = params[:consultation] 
    if @consultation.save 
     redirect_to thank_you_path 
    else 
     render :layout => "simple" 
    end 
    else 
    render :layout => "simple" 
    end 
end 

ネストされたオブジェクトを検証し、エラーを処理するために私のための適切な方法は何ですか? before_validationメソッドにnew_record?を使用する必要がありますか?

更新:@ Validity_associatedという@ Adityaの提案を使用しても、それでも更新されたデータは検証されません。私が入れた更新された時間は有効になっていますが、有効ではないので保存されず、古いデータで再度検証され、検証/検証に失敗し、その日付の警告が表示されます。

私には何が欠けていますか?

アップデート2:私はイベントの順序を確認するためにP文の束を追加し、私はvalidated_associatedを残せば、それは一度だけ検証しますが、何らかの理由で会議自体が罰金保存し、したがって、それはリダイレクトありがとうございます。しかし、私はそれを残して、それは2回、したがって問題を検証します。それで、最初の(または2番目の)時間を検証するのはなぜですか?それをどうやって止めるのですか?

更新3:私はproposed_times_attributes=という機能を使い果たし、そこにタイムゾーンを追加しました。これで問題が解決しました(@ Adityaの方法と一緒に)。私はそのような定義された方法で動作させる方法を知りたがっています。私はvalidates_associatedaccepts_nested_attributes_forを持っていない/持っていないというさまざまな組み合わせを試し、その機能を定義しました。

あなたがこれに遭遇して、proposed_times_attributes=を書く方法を知っていれば、検証はまだ動作しますので、教えてください。proposed_times_attributes=に私は1つ入れたいと思っています。すべての提案された時間のためのタイムゾーン選択ボックス。*_attributes=()メソッドの中でsuper()を呼び出す方法があったと思います。

+0

関連を定義するときに:validatesオプションを見たことがありますか? –

答えて

1

最後にそれを分かりました。したがってassign_nested_attributes_for_collection_associationまたはassign_nested_attributes_for_one_to_one_associationを呼び出すことによってsuper()型のメソッドを実行できます。しかし、これらのメソッドのオプションのいくつかを設定するには、accepts_nested_attributes_forも呼び出す必要があります(それぞれのドキュメントを見るには関数の名前をクリックしてください)。

accepts_nested_attributes_for :advisor, :client, :proposed_times 
... 
def proposed_times_attributes=(attributes) 
    attributes.each do |key,value| 
    value[:timezone] = client.timezone 
    end 
    assign_nested_attributes_for_collection_association(:proposed_times, attributes) 
end 
0

@RyanJMあなたは既に次の会合を持っていると仮定すると、次の

meeting.rb

validates_associated :proposed_times 

を使用する場合は、手動で子関連付けるエンティティを検証する必要はありません

あなたのmeeting.rb

has_many :proposed_times 
+0

私はそれを見ていませんでした。私はそれを追加したばかりですが、まだ更新されたデータを検証して失敗し、失敗したデータを使用するのではなく古いデータを検証します。何故それを2回チェックするのか? – RyanJM

関連する問題