Я работаю над приложением, которое обрабатывает временные карточки сотрудников, и я пытаюсь создать форму, которая позволяет сотрудникам редактировать все свои удары в заданном блоке время. Я использовал this RailsCast в качестве основы для формы, и был в состоянии получить вещи и работает без проблем:Rails 3 - Проверка нескольких экземпляров модели друг против друга
class BlocksController < ApplicationController
def update
@block = Block.find_by_id(params[:id])
@punches = @block.punches
keys = params[:punches].keys
values = keys.map { |k| params[:punches][k] }
@punches = Punch.update(keys, values).reject { |p| p.errors.empty? }
if @punches.empty?
flash[:notice] = "Punches updated"
redirect_to employee_timecard_path(current_user, @block.timecard)
else
render :action => "edit"
end
end
Проблема, однако, заключается в том, что мне нужно, чтобы иметь возможность проверить, что пользователь не сделал отредактируйте свои удары таким образом, чтобы это не имело смысла (например, изменение их часового удара было более поздним, чем ударный удар, или наоборот).
Я пробовал делать это с помощью выборочной проверки модели, но отдельные модели, проходящие через проверку, не знают о других обновляемых значениях, поэтому первый удар в пакете сравнивает его новое значение с значениями предварительного обновления других.
Единственный другой подход, о котором я мог думать, состоял в том, чтобы пропустить params[:punches]
, отправляемый методу обновления в контроллере, но это, похоже, противоречит соглашению «толстая модель, тощий контроллер».
Есть ли способ, которым я могу иметь свой торт и съесть его тоже? Любые предложения будут высоко ценится.
Я все еще думаю, что вы как бы застреваете в пуансонах в блочном контроллере. Контроллерам должно быть позволено расти, если это уместно. В вашем случае я думаю, что это так. Единственное, что я мог подумать об уменьшении кода контроллера, было неэффективным, без необходимости называть уровень ActiveModel просто для того, чтобы держать контроллер тонким, не похоже на хороший компромисс, вроде как курить сигареты, чтобы оставаться тонким! – RadBrad
Не могли бы вы использовать фильтр после или вокруг? Самое худшее, что вы могли бы сделать, это сохранить все в базе данных, проверить его после фильтра, а затем как-то его отменить. Я не очень хорошо разбираюсь в фильтрах, но из того, что я собираю, вы можете проверить обновления как группу до их сохранения и прервать сохранение, если ваши проверки не удались. См. Http://guides.rubyonrails.org/action_controller_overview.html # filters –
Насколько я знаю, вы можете настроить метод класса для Punches, который проверяет весь набор (или некоторое подмножество подмножества) записей (возможно, возвращает список идентификаторов для записей, которые не работают, например). –