Rails 4: 验证失败时再次渲染 controller/action
Rails 4: render controller/action again when validation fails
已经有几个问题解决了这个问题:
- render/redirect to new action when validation fails (rails)
- Keeping validation errors after redirect from partial back to the same page that has the partial
我尝试实施一些推荐的解决方案,但未能解决我的问题。
我们开始吧。
在我的Rails4 app中,有四种模式:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
has_many :invitations, :class_name => "Invite", :foreign_key => 'recipient_id'
has_many :sent_invites, :class_name => "Invite", :foreign_key => 'sender_id'
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many :invites
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Invite < ActiveRecord::Base
belongs_to :calendar
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
在这里,我们将重点关注 Invite
和 Calendar
模型。
在日历 edit
视图中,我有一个 create
新邀请的表格:
<h2>Edit <%= @calendar.name %> calendar</h2>
<%= render 'form' %>
<h2>Invite new users to <%= @calendar.name %> calendar</h2>
<%= form_for @invite , :url => invites_path do |f| %>
<%= f.hidden_field :calendar_id, :value => @invite.calendar_id %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label "Role" %>
<%= f.radio_button(:recipient_role, "Editor") %>
<%= f.label "Editor" %>
<%= f.radio_button(:recipient_role, "Viewer") %>
<%= f.label "Viewer" %>
<%= f.submit 'Send' %>
<% end %>
<%= link_to 'Show', calendar_path %> |
<%= link_to 'Back', calendars_path %>
–––––
UPDATE:请注意,我已经为我的日历视图定义了一个 calendars.html.erb
布局,包括以下用于显示提醒的代码:
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
<%= value %>
</div>
<% end %>
–––––
在 Invite
模型中,我想验证 :email
和 :recipient_role
的存在(这两个值都是用户通过表单提交的),所以我将其添加到Invite
型号:
validates :email, :recipient_role, presence: true
如果用户忘记填写这两个字段之一,我希望用户被重定向到带有错误消息的表单,我在 InvitesController
:[=33= 中使用以下代码实现了这一点]
class InvitesController < ApplicationController
def create
# some code
if @invite.save
# some code
else
format.html { render :template => "calendars/edit", notice: 'Invitation could not be sent.' }
end
redirect_to calendar_path(@calendar), notice: 'Invitation was successfully sent.'
end
private
def invite_params
params.require(:invite).permit(:email, :calendar_id, :recipient_role)
end
end
特别是,我认为 format.html { render :template => "calendars/edit", notice: 'Invitation could not be sent.' }
行可以让我做我想做的事,as recommended here。
但是,当我尝试提交至少包含一个空字段的表单时,出现以下错误:
ArgumentError in InvitesController#create
too few arguments
end
else
format.html { render :template => "calendars/edit", notice: 'Invitation could not be sent.' }
end
redirect_to calendar_path(@calendar), notice: 'Invitation was successfully sent.'
end
这是服务器日志:
Processing by InvitesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"p+yxM9Tw3JiNw/6Chv9//N8uvWhMy0TqrudTu0y9D9zXCl6kK2LtCqPu1rvTGv5gOMBuv2RK/IX2MBpWUTelZw==", "invite"=>{"calendar_id"=>"3", "email"=>"test@example.com"}, "commit"=>"Send"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Calendar Load (0.1ms) SELECT "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1 [["id", 3]]
(0.0ms) begin transaction
(0.0ms) rollback transaction
Completed 500 Internal Server Error in 27ms (ActiveRecord: 1.3ms)
ArgumentError (too few arguments):
app/controllers/invites_controller.rb:16:in `format'
app/controllers/invites_controller.rb:16:in `create'
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (3.7ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.9ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (54.0ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.4ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (36.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.2ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (83.2ms)
我做错了什么?
请做以下事情
def create
# some code
if @invite.save
redirect_to calendar_path(@calendar), notice: 'Invitation was successfully sent.'
else
render template: "calendars/edit", notice: 'Invitation could not be sent.'
end
end
已经有几个问题解决了这个问题:
- render/redirect to new action when validation fails (rails)
- Keeping validation errors after redirect from partial back to the same page that has the partial
我尝试实施一些推荐的解决方案,但未能解决我的问题。
我们开始吧。
在我的Rails4 app中,有四种模式:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
has_many :invitations, :class_name => "Invite", :foreign_key => 'recipient_id'
has_many :sent_invites, :class_name => "Invite", :foreign_key => 'sender_id'
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many :invites
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Invite < ActiveRecord::Base
belongs_to :calendar
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
在这里,我们将重点关注 Invite
和 Calendar
模型。
在日历 edit
视图中,我有一个 create
新邀请的表格:
<h2>Edit <%= @calendar.name %> calendar</h2>
<%= render 'form' %>
<h2>Invite new users to <%= @calendar.name %> calendar</h2>
<%= form_for @invite , :url => invites_path do |f| %>
<%= f.hidden_field :calendar_id, :value => @invite.calendar_id %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label "Role" %>
<%= f.radio_button(:recipient_role, "Editor") %>
<%= f.label "Editor" %>
<%= f.radio_button(:recipient_role, "Viewer") %>
<%= f.label "Viewer" %>
<%= f.submit 'Send' %>
<% end %>
<%= link_to 'Show', calendar_path %> |
<%= link_to 'Back', calendars_path %>
–––––
UPDATE:请注意,我已经为我的日历视图定义了一个 calendars.html.erb
布局,包括以下用于显示提醒的代码:
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
<%= value %>
</div>
<% end %>
–––––
在 Invite
模型中,我想验证 :email
和 :recipient_role
的存在(这两个值都是用户通过表单提交的),所以我将其添加到Invite
型号:
validates :email, :recipient_role, presence: true
如果用户忘记填写这两个字段之一,我希望用户被重定向到带有错误消息的表单,我在 InvitesController
:[=33= 中使用以下代码实现了这一点]
class InvitesController < ApplicationController
def create
# some code
if @invite.save
# some code
else
format.html { render :template => "calendars/edit", notice: 'Invitation could not be sent.' }
end
redirect_to calendar_path(@calendar), notice: 'Invitation was successfully sent.'
end
private
def invite_params
params.require(:invite).permit(:email, :calendar_id, :recipient_role)
end
end
特别是,我认为 format.html { render :template => "calendars/edit", notice: 'Invitation could not be sent.' }
行可以让我做我想做的事,as recommended here。
但是,当我尝试提交至少包含一个空字段的表单时,出现以下错误:
ArgumentError in InvitesController#create
too few arguments
end
else
format.html { render :template => "calendars/edit", notice: 'Invitation could not be sent.' }
end
redirect_to calendar_path(@calendar), notice: 'Invitation was successfully sent.'
end
这是服务器日志:
Processing by InvitesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"p+yxM9Tw3JiNw/6Chv9//N8uvWhMy0TqrudTu0y9D9zXCl6kK2LtCqPu1rvTGv5gOMBuv2RK/IX2MBpWUTelZw==", "invite"=>{"calendar_id"=>"3", "email"=>"test@example.com"}, "commit"=>"Send"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Calendar Load (0.1ms) SELECT "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1 [["id", 3]]
(0.0ms) begin transaction
(0.0ms) rollback transaction
Completed 500 Internal Server Error in 27ms (ActiveRecord: 1.3ms)
ArgumentError (too few arguments):
app/controllers/invites_controller.rb:16:in `format'
app/controllers/invites_controller.rb:16:in `create'
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (3.7ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.9ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (54.0ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.4ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (36.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.2ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (83.2ms)
我做错了什么?
请做以下事情
def create
# some code
if @invite.save
redirect_to calendar_path(@calendar), notice: 'Invitation was successfully sent.'
else
render template: "calendars/edit", notice: 'Invitation could not be sent.'
end
end