質問

より具体的には、 "モデルで少なくともx個の有効な関連モデルを作成する必要があることを検証するにはどうすればよいですか? 。私は、親と同じ形式で作成されたネストされたモデルを検証しようとしました(そして最終的にはjQueryでの即時検証を表示します)。一般的な例として、次のモデルとスキーマを想定してみましょう。

class Project
  include DataMapper::Resource

  property :id,     Serial
  property :title,  String, :nullable => false

  has 2..n, :tasks
end

class Task
  include DataMapper::Resource

  property :id,         Serial
  property :project_id, Integer,  :key => true
  property :title,      String,   :nullable => false

  belongs_to :project
end

すべての検証は、ご覧のとおりスキーマ定義で行われます。ここで重要なのは" has 2..n、:tasks "です。 paramsハッシュのネストされたタスク属性が valid タスクを生成することを考えると、この検証は実際に正常に機能します。ただし、無効なタスクを生成した場合、タスクは作成されず、2つ未満のタスクを持つプロジェクトになります。したがって、無効な >プロジェクトオブジェクト。

私が理解しているように、これはタスクを保存しようとするまでタスク属性が有効かどうかわからないためです-私の知る限り-プロジェクトの前にタスクを保存することはできません。プロジェクトは、タスクが有効かどうかを認識しません。私はこれを仮定して正しいですか?

とにかく、すぐに答えが出ることを望んでいましたが、思っていたよりもささいなことではないようです。何か提案があれば、それは大歓迎です。

役に立ちましたか?

解決

実際に、DataMapperのトランザクションを使用して、ここで素晴らしいソリューションを見つけました。基本的に、このトランザクションは親オブジェクトとすべての子オブジェクトを保存しようとします。保存に失敗するとすぐに、トランザクションは停止し、何も作成されません。すべてがうまくいけば、オブジェクトは正常に保存されます。

class Project
  def make
    transaction do |trans|
      trans.rollback unless save
      tasks.each do |task|
        unless task.save
          trans.rollback
          break
        end
      end
    end
  end
end

これにより、すべてが保存される前にすべてが有効になります。コントローラコードで#saveおよび#updateメソッドを#makeに変更する必要がありました。

他のヒント

SET CONSTRAINTS DEFERREDは、データベースエンジンがサポートしている場合に便利です。

それ以外の場合、ストアドプロシージャを作成して挿入を実行し、そのストアドプロシージャの妥当性を確認して、正しい検証済みデータのみが挿入されるようにします。

モデルオブジェクトが保存される前に検証を実行する valid?というモデルメソッドがあります。したがって、関連付けを検証する簡単な方法は、 validates_with_block 'または' validates_with_method を使用して、関連付けの検証をチェックすることです。

次のようになります

validates_with_block do
  if @tasks.all?{|t|t.valid?}
    true
  else
    [false, "you have an invalid task"]
  end
end

または dm-association-validator または dm-accepts-nested-attributes

編集:クレイジーになります。タスクの検証を実行してから、関連付けに関連するエラーのみがエラーであるかどうかを確認します。

validates_with_block do
  if @tasks.all?{|t|t.valid?;!t.errors.any?{|e|e[0]==:project}}
    true
  else
    [false, "you have an invalid task"]
  end
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top