私は Ruby と Rails (2.3.8 を使用) の両方にかなり慣れていないので、ここで明らかな何かが欠けている場合はご容赦ください。
私のコードにはプランがあり、プランには多くの Plan_Steps があります。各 Plan_Step には番号があります (「1st」、「2nd」などを示すため)。Plan を更新するためのフォームがあり、各 Plan_Step に一意の番号があることを検証する必要があります。以下のコードは、設計のより良い説明を与えるかもしれません:
モデル/plan.rb:
Class Plan < ActiveRecord::Base
has_many :plan_steps
accepts_nested_attributes_for :plan_steps, :allow_destroy => true
validate :validate_unique_step_numbers
# Require all steps to be a unique number
def validate_unique_step_numbers
step_numbers = []
plan_steps.each do |step|
#puts step.description
if !step.marked_for_destruction? && step_numbers.include?(step.number)
errors.add("Error Here")
elsif !step.marked_for_destruction?
step_numbers << step.number
end
end
end
コントローラー/plans_controller.rb:
...
def update
@plan = Plan.find(params[:id])
if @plan.update_attributes(params[:plan])
#Success
else
#Fail
end
end
フォームが更新を送信すると、params ハッシュは次のようになります。
{"commit"=>"Submit",
"action"=>"update",
"_method"=>"put",
"authenticity_token"=>"NHUfDqRDFSFSFSFspaCuvi/WAAOFpg5AAANMre4x/uu8=",
"id"=>"1",
"plan"=>{
"name"=>"Plan Name",
"plan_steps_attributes"=>{
"0"=>{"number"=>"1", "id"=>"1", "_destroy"=>"0", "description"=>"one"},
"1"=>{"number"=>"2", "id"=>"3", "_destroy"=>"0", "description"=>"three"},
"2"=>{"id"=>"2", "_destroy"=>"1"}},
"controller"=>"plans"}
データベースには、次の Plan_Steps のエントリが含まれています。
ID=1, Number=1, Description='one'
ID=2, Number=2, Description='two'
ID=2 が Number=2 で存在することに注意してください。私がしようとしているのは、ID=2 を削除し、Number=2 で新しいエントリ (ID=3) を作成することです。
OK、その設定で、ここに私の問題があります:
検証で plan_steps を呼び出すと、update_attributes に渡された params[] 配列からではなく、データベースから値を取得しているように見えます。
たとえば、検証で「puts」行のコメントを外すと、Plan_Steps の説明は、渡されたパラメーターから存在するものとしてではなく、データベース内に存在するものとして表示されます。これは、受信した Plan_Steps を検証できないことを意味します。
Plan_Steps モデルで検証を行うこともできません。間違っていない限り、検証はデータベースに対して行われるためです (渡されたパラメーターではありません)。
これが言葉遣いの悪い質問である場合は申し訳ありませんが、かなり具体的です。説明が必要な場合は、お尋ねください。
そして、覚えておいてください、私は初心者なので、本当にばかげた間違いを簡単に犯す可能性があります.