Исходное название: before_validation при обновлении - ошибка не обрабатывается должным образом
Я пытаюсь выяснить, как обрабатывать проверку вложенного объекта, особенно при обновлении.
Мой родительский класс, который обрабатывает вложенные атрибуты.
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
Класс, который я пытаюсь проверить, ниже. В основном мне нужно подтвердить, что дата в будущем. И я создаю свой initial_at с помощью before_validation
метода. Так что я не уверен, как справиться со случаем, когда (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
Как мне правильно проверить вложенный объект и обработать ошибки? Нужно ли использовать new_record?
для метода before_validation
?
Обновление : Таким образом, используя предложение @ Aditya о validates_associated, оно по-прежнему не проверяет только обновленные данные. Обновленные времена, которые я вставляю, проверяются ... но, поскольку они недействительны, они не сохраняются, а затем снова проверяются (со старыми данными), а затем проходит / не проходит проверку и отображаются предупреждения для этих дат .
Что мне не хватает?
Обновление 2 : я добавил кучу операторов p, чтобы увидеть порядок событий, и если я опущу validated_associated
, он будет проверен только один раз, но по какой-то причине сама конференция сохраняет хорошо, и поэтому он перенаправляет, чтобы поблагодарить вас. Но если я оставлю это, он проверяет дважды, отсюда и проблемы. Так почему же это проверка первого (или второго) раза и как мне это остановить?
Обновление 3 : Хорошо, поэтому я удалил свою функцию proposed_times_attributes=
и добавил в нее часовой пояс. Это решило проблему (вместе с методом @ Aditya). Хотелось бы знать, как заставить его работать с таким методом. Я пробовал различные другие комбинации наличия / отсутствия validates_associated
, accepts_nested_attributes_for
и определения этой функции.
ТАК, если вы сталкиваетесь с этим и знаете, как написать proposed_times_attributes=
, чтобы проверка работала, пожалуйста, дайте мне знать. Мне нужно иметь возможность указать часовой пояс в proposed_times_attributes=
, потому что я хотел бы посмотреть поставить один флажок выбора часового пояса для всех предлагаемых времен. Я хотел бы, чтобы был способ вызвать super () внутри метода *_attributes=()
.