ruby on rails - كيف يمكن التحقق من صحة كائن نموذج متداخل بناءً على حالة الكائن الرئيسي؟




ruby-on-rails ruby-on-rails-3 (2)

إضافة سمة افتراضية في نموذج Address الخاص بك:

class Address < ActiveRecord::Base
  belongs_to :participant
  attr_accessor :skip_validation
  validates_presence_of :address1, :state, :suburb, :postcode, 
                           :unless => :skip_validation 
end

قم بتعيين السمة الظاهرية على كائن العنوان عند تعيين current_step .

class Participant < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
  attr_accessor :current_step
  validates_presence_of :first_name, :last_name, 
                         :if => lambda {|r| r.current_step == "name"}


  def current_step=(value)
    unless (value == "address")
      address.skip_validation = true
    end    
    @current_step = value 
  end    
end

أنا أكتب نموذج المعالج في القضبان. على سبيل المثال ، صفحات الإدخال المتعددة لكائن نموذجي واحد.

أساسيات النهج الخاص بي هي تلك التي تم وصفها في رايليتس Brian's Multistep: railscast: http://railscasts.com/episodes/217-multistep-forms (في حال أراد أي شخص معرفة السبب وراء بعض الكود أدناه).

الأشياء تحت الفحص هنا هي "مشارك" ، والتي تحتوي على "عنوان" واحد

مشكلتي هي أنني أريد فقط التحقق من صحة الكائن المتداخل (العنوان) عندما يحاول المستخدم التقدم بعد شاشة إدخال العنوان. يتم تتبع ذلك حاليًا عبر سمة على نموذج المشارك تسمى "current_step"

لذلك لديّ مشارك:

class Participant < ActiveRecord::Base
  has_one :address
  accepts_nested_attributes_for :address
  validates_presence_of :first_name, :last_name, :if => self.current_step == "name"
  ...
  def steps = %w[ name address confirm ] # the steps the wizard will follow
end

و العنوان:

class Address < ActiveRecord::Base
  belongs_to :participant
  validates_presence_of :address1, :state, :suburb, :postcode #, :if => participant.current_step == "address"
end

مبدأ هذا النهج هو إجراء "إنشاء" يسمى على وحدة تحكم (غير معروض) لكل خطوة من خطوات المعالج ، ويقوم فقط بالتحقق من صحة مجموعة فرعية من النموذج عند معالجة كل خطوة.

في الوقت الحالي ، عندما أكمل أول شاشة ("اسم") وحاول الانتقال إلى خطوة العنوان ، يتم تشغيل التحقق من صحة العنوان ، ويتم إعادلي إلى شاشة "الاسم" مع وجود أخطاء التحقق من صحة تفاصيل العنوان الفارغ.

لذا فقد جربت عددًا من الطرق هنا ، الجزء الأخير منها كان الشرط المعلق على التحقق من العنوان الموضح أعلاه - هذا وجدته لا يعمل كما أقوم فقط ببناء مشارك-> كائنات العناوين ، ولكن لا يتم حفظها معهم. ولذلك يحصل @participant.address على عنصر العنوان ، ولكن @participant.address.participant فارغ لأن العنوان ليس به بعد مفتاح خارجي مشترك للبحث عنه هو الأصل.

يبدو أن السبب في accepts_nested_attributes_for طريقة accepts_nested_attributes_for فائقة الاستخدام. كنت أتوقع استخدام validates_associated لإجراء التحقق من الصحة ، ولكن أرى أن علامة accepts_nested_attributes_for حد سواء accepts_nested_attributes_for المعلمات شكل لطيف لإنشاء كائنات نموذج المتداخلة ، ولكن أيضا يضمن participant#valid? يستدعي الأسلوب إلى التحقق من صحة العنوان في جميع الحالات.

لذلك معضلة هي أفضل طريقة لاستخدام participant#valid? طريقة للتحقق من صحة النموذج الكامل جزئيًا ، استنادًا إلى المعلمة current_step في المشارك؟

EDIT - تم تحديثه لإزالة معلومات إضافية ، والتقط إلى المشكلة الأساسية


على الرغم من أن أساليب "التحقق من صحة" ActiveRecord مريحة للغاية ، لا يوجد شيء before_save من "المتداول الخاصة بك" ، ربما باستخدام hooks before_save . يمكنك استبدال validates_presence_of على Address مع ربط before_save الذي لا تحقق فقط في ظل ظروف معينة. ثم accepts_nested_attributes_for يفترض أن لا تراه.







activerecord