Rails - пользователь нажимает «Назад» после создания объекта, создания дубликатов - PullRequest
6 голосов
/ 06 декабря 2011

У меня возникла проблема, когда пользователь заполняет мою форму оценки, нажимает «Создать», затем нажимает кнопку «Назад» в браузере, вносит некоторые изменения и снова нажимает «Создать», это создает повторяющиеся оценки.

Каков наилучший способ предотвратить что-то подобное?

Только ОДИН evaluation должен существовать для каждого survey_criterion при создании.Я не хочу, чтобы пользователь терял введенные данные после нажатия кнопки «Назад», заполнения формы новым материалом и повторного нажатия кнопки «Создать».

ОБНОВЛЕНИЕ

rout.rb

resources :survey_criteria do
  resources :groups do
    resources :evaluations
  end
end

survey_criterion.rb

has_many :evaluations

valuation.rb

belongs_to :survey_criterion
belongs_to :group

Есть более сложные ассоциации, но ответ я 'я ищу больше, «как это сделать, когда пользователи нажимают кнопку« Назад », изменяют форму, затем нажимают« Создать заново »».

Я хочу обновить тот, который был автоматически создан, я думаюв этом случае и не выдавать ошибку пользователю.Я знаю, что могу добавить проверку, которая выдает ошибку, но я хочу, чтобы это было невидимым для пользователя.

Мысли?

Ответы [ 4 ]

7 голосов
/ 06 декабря 2011

Самое простое решение - изменить действие create, которое должно работать следующим образом:

def create
  # ...
  if evaluation_exists?
    update_evaluation(params[:evaluation])
  else
    create_evaluation(params[:evaluation])
  end
  # ...
end

Что касается вашего вопроса "как с ним справиться, когда пользователи нажимают кнопку" Назад ", изменяют форму, затем нажимают кнопку" Создать заново ", затем я использую некоторый случайный токен (короткая строка) помещается как скрытое поле в форме.

Когда приходит запрос на создание, я проверяю, сохранен ли этот токен в сеансе. Если это не так, то я создаю объект и добавляю этот токен в список используемых. Если токен уже присутствует в сеансе, я знаю, что пользователь только что повторно отправил форму, и я могу действовать соответственно. Обычно я спрашиваю его, должен ли быть создан другой объект. В сеансе я обычно храню не более 3-5 токенов.

Это выглядит так (да, это просто иллюстрация) :

def create
  token = params[:token]
  session[:tokens] ||= []
  if session[:tokens].include? token
    render_the_form_again( "You have already created the object. Want another?" )
  else
    create_the_object
    session[:tokens] << token
  end
  # ...
end
1 голос
/ 24 августа 2012

Вы также можете сделать 2 вещи:

  1. Запретить кэш браузера.
  2. Отключить кнопку Создать с помощью: disable_with => «Обработка».

Здесь также обсуждается: https://stackoverflow.com/a/12112007/553371

1 голос
/ 06 декабря 2011

В вашей модели оценки добавьте эту строку:

validates_uniqueness_of :survey_criterion_id

Предполагается, что SurveyCriterion содержит внешний ключ, связанный с вашей оценкой.

0 голосов
/ 13 июля 2012

Менее элегантный, но более общий способ сделать это - использовать history.pushState.На странице после создания:

$(function(){
  if(history.pushState){
    window.onpopstate = function(event){
      if(window.history.state && window.history.state.previousStep){
        window.location = window.history.state.previousStep;
      }
    }
    window.history.replaceState({ previousStep: '#{edit_resource_url(resource)}'}, document.title, window.location);
    window.history.pushState({}, document.title, window.location);
  }

})

В этом примере используется HTML5 History API.Подобное можно сделать с помощью отката, используя history.js проект

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...