#ruby-on-rails
#ruby-on-rails
Вопрос:
Некоторое время пытался разобраться в этом, но не смог расколоть гайку.
Что я пытаюсь сделать, так это это.
У меня есть пользовательская модель, в ней есть множество ответов. Я хотел бы ограничить возможность для одного пользователя отвечать на один и тот же ответ более одного раза. Я смог заблокировать это в модели, но не в представлении.
Я хотел бы, чтобы кнопка отправки отображала, является ли current_user.id присутствует в текущем идентификаторе ответа (тот, который он собирается заполнить), если это так, отключите кнопку отправки с надписью «уже применен».
Мои ответы#новое
<%= form_for @answer do |f| %>
<%= f.hidden_field :application_id, value: @application.id %>
<% if @application.question_2.length amp;amp; @application.question_3.length >= 1 %>
<p>Question 1: <%= @application.question_1 %></p>
<%= f.text_area :answer_1 %><br/>
<p>Question 2: <%= @application.question_2 %></p>
<%= f.text_area :answer_2 %><br/>
<p>Question 3: <%= @application.question_3 %></p>
<%= f.text_area :answer_3 %>
<% elsif @application.question_2.length >= 1 %>
<p>Question 1: <%= @application.question_1 %></p>
<%= f.text_area :answer_1 %><br/>
<p>Question 2: <%= @application.question_2 %></p>
<%= f.text_area :answer_2 %><br/>
<% else %>
<p>Question 1: <%= @application.question_1 %></p>
<%= f.text_area :answer_1 %><br/>
<% end %>
<%= f.submit "Submit answers", data: { disable_with: "Please wait..." } %>
<% end %>
Комментарии:
1. Мне это непонятно.
@answer
это новая запись. Откуда вы знаете, что этот возможный ответ совпадает с ответом, который уже есть вcurrent_user.answers
? Вы хотите сказать, что у пользователя не может быть двух ответов на один и тот же вопрос@application
?2. @SteveTurczyn да, пользователь не должен иметь два ответа для одного и того же приложения.
Ответ №1:
Предполагая, что ответ принадлежит приложению, вы могли бы сделать…
<% if current_user.answers.collect(amp;:application).include?(@application) %>
<%= f.submit "already applied", disabled: true %>
<% else %>
<%= f.submit "Submit answers", data: { disable_with: "Please wait..." } %>
<% end %>
Ответ №2:
Я вижу пару разных фрагментов этого. Когда я пишу подобную функциональность, я думаю о следующих вопросах:
- Что должно произойти при загрузке / перезагрузке страницы?
- Должно ли что-либо произойти без перезагрузки страницы (т.Е.. через AJAX / JS)?
- Должно ли действие быть отключено на стороне сервера, на стороне клиента или на обоих?
Прежде всего, если пользователь уже отправил ответ ко времени загрузки страницы, шаблон должен отображать кнопку по-другому. Обычно в этом случае имеет смысл вообще не отображать форму, но если вы хотите, чтобы форма с отключенной кнопкой была отключена, на ум приходит следующий код (см. html-пример):
<% if @user_has_answered %>
<%= f.submit "Submit answers", disabled: true %>
<% else %>
<%= ... normal button ... %>
<% end %>
Если вы обеспокоены тем, что пользователь не сможет дважды нажать кнопку при отправке формы со страницы, какой-нибудь простой Jquery может легко справиться с этим, или вы можете использовать disable_with
, как в вашем примере, дважды. Это не имеет ничего общего с состоянием базы данных; это просто настраивает прослушиватель Javascript, который отключает кнопку, как только на нее нажимают (и изменяет ее текст), чтобы предотвратить случайную двойную отправку пользователем при медленной загрузке страниц.
Вы упомянули, что вы предотвратили двойные ответы в модели. Как контроллер справляется с этим? Если пользователю каким-то образом удается заполнить форму во второй раз и отправить ее (возможно, Javascript отключен, и у них было открыто несколько вкладок на одной странице? Если это возможно, пользователи делают это), что вы хотите, чтобы произошло с данными, которые они отправили? Показать им сообщение об отклонении? Сохранить свои данные на той же странице? Эта функциональность должна быть на 80% автоматической в Rails, если вы этого хотите, при условии, что вы обрабатываете запрос и отклонение таким же образом, как обрабатываются ошибки проверки формы.
Я буду рад быть более конкретным, если вы поделитесь более подробной информацией о том, что вы ищете или с чем у вас возникли проблемы.