#ruby-on-rails #ruby-on-rails-4
#ruby-on-rails #ruby-on-rails-4
Вопрос:
У меня вопрос к rails. Я создаю форму для регистрации пользователя. Что я хочу сделать, так это то, что после того, как пользователь нажмет кнопку «Отправить», я хочу перенаправить пользователя на другую страницу, на которой отображается вся информация из формы, заполненной пользователем только что (только для чтения).
Это мой контроллер
class PermitsController < ApplicationController
before_action :set_permit, only: [:show, :destroy]
def index
@permits = Permit.all
end
def new
@permits = Permit.new
end
def create
@permits = current_user.permits.build(permit_params)
if @permits.save
redirect_to invoice_path
else
render 'new'
end
end
def destroy
Permit.destroy_all(user_id: current_user)
respond_to do |format|
format.html { redirect_to root_path, notice: 'Permit was successfully canceled.' }
format.json { head :no_content }
end
end
def invoice
@permits = current_user.permits(permit_params)
end
def show
@user = User.find(params[:id])
@permits = @user.permits.paginate(permit_params)
end
def update
@permits = Permit.where(user_id: current_user).take
respond_to do |format|
if @permits.update(permit_params)
format.html { redirect_to root_path}
flash[:success] = "Permit successfully updated"
format.json { render :show, status: :ok, location: @user }
else
format.html { render :edit }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permit
@permits = Permit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permit_params
params.require(:permit).permit(:vehicle_type, :name, :studentid, :department, :carplate, :duration, :permitstart, :permitend)
end
end
Это форма, заполненная пользователем
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@permits) do |f| %>
<%= f.label :"Vehicle" %>
<%= f.text_field :vehicle_type, class: 'form-control' %>
<%= f.label :"License Plate" %>
<%= f.text_field :carplate, class: 'form-control' %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, class: 'form-control' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :"Department of applicant" %>
<%= f.text_field :department, class: 'form-control' %>
<%= f.label :permit_start %>
<%= f.date_select :permitstart, class: 'form-control' %>
<%= f.label :permit_end %>
<%= f.date_select :permitend, class: 'form-control' %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
Ответ №1:
Вы могли бы добавить дополнительное действие между new
и create
.
# config/routes.rb
resources :permit do
collection do
post :confirm
end
end
Причина, по которой мы используем POST, даже если маршрут не создает ресурс, заключается в том, что мы не хотим передавать какую-либо информацию о пользователе в URL-адресе запроса.
class PermitsController < ApplicationController
# POST /permits/confirm
def confirm
@fields = %i[vehicle_type, carplate, studentid, name, department, permitstart, permitend]
@permit = current_user.permits.build(permit_params)
render :new and return unless @permit.valid?
end
end
render :new and return unless @permit.valid?
ускоряет процесс и :new
повторно отображает форму, если входные данные изначально недопустимы.
Поскольку мы используем POST, нам нужна форма как для, так new.html.erb
и confirm.html.erb
для всех, дублирование всех этих входных данных было бы нецелесообразным, поэтому давайте извлекаем их до частичного:
<% # /views/permits/_inputs.html.erb %>
<%
input_options ||= {}
input_options[:class] ||= 'form-control'
%>
<%= f.label :"Vehicle" %>
<%= f.text_field :vehicle_type, input_options%>
<%= f.label :"License Plate" %>
<%= f.text_field :carplate, input_options %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, input_options %>
<%= f.label :name %>
<%= f.text_field :name, input_options %>
<%= f.label :"Department of applicant" %>
<%= f.text_field :department, input_options %>
<%= f.label :permit_start %>
<%= f.date_select :permitstart, input_options %>
<%= f.label :permit_end %>
<%= f.date_select :permitend, input_options %>
Итак, давайте укажем new.html.erb
форму так, чтобы она отправлялась в /permits/confirm
:
<% provide(:title, 'New Permit') %>
<h1>Permit Application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@permits, url: '/permits/confirm_permits_path') do |f| %>
<% render partial: :inputs %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
И создайте /views/permits/confirm.html.erb
представление:
<% provide(:title, 'Confirm Permit application') %>
<h1>Confirm Permit application</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@permits) do |f| %>
<% render partial: :inputs, input_options: { readonly: 'readonly' } %>
<% end %>
</div>
</div>
Комментарии:
1. На заметку — вам нужно очистить свой код, когда дело доходит до согласованности и идемпотентности. Обратите внимание на плюрализацию при именовании переменных. Используется
@permit
, когда переменная содержит одну запись. Придерживайтесь snake_case при именовании переменных, методов и столбцов. Другие будут вам благодарны, и вам будет легче выявлять ошибки. github.com/bbatsov/ruby-style-guide2. Странно, я точно следовал предложенному вами методу, но я получил эту ошибку «‘:inputs’ не является объектом, совместимым с ActiveModel. Он должен реализовывать:to_partial_path . » Означает ли эта ошибка, что у меня какая-то ошибка именования? Я создал новый view /views/permits/_inputs.html.erb . Относится ли _inputs.html.erb к входным данным?