我正在努力构建rails 3 + devise,用户注册页面。这将是一个额外的页面,不会取代现有的设计注册页面。此页面将包含用户信息和结算信息。
我正在尝试提交表单,如果表单字段没有保存,请让重新加载的页面包含用户以前输入的数据。这是一个片段:
<%= form_for(User.new, :url => '/pricing/sign_up') do |f| %>
<%= f.label :email %>
<%= f.email_field :email %>
<% end %>
当表单提交无效数据时。当视图重新渲染时,输入的现有电子邮件不会保留。如何使现有用户的输入保持不变,以帮助用户快速纠正错误并提交有效表单?
由于
答案 0 :(得分:6)
关键是让form_for
使用正确的对象。所以,而不是
<%= form_for(User.new, :url => '/pricing/sign_up') do |f| %>
你应该使用一个实例变量来包含这个对象,比如这个
<%= form_for(@user, :url => '/pricing/sign_up') do |f| %>
控制器操作如下所示:
# Note: this may need to be an `edit` method instead?
def new
@user = User.new
end
# Note: this may need to be an `update` method instead?
def create
@user = User.new(params[:user])
if @user.save
# Do something... Usually a redirect with success message.
else
render :new
end
end
这个create方法正在做的是用表单中的params填充@user
对象。然后调用@user.save
将在后台调用@user.valid?
,如果没有返回错误,则记录将保存到数据库中。但这部分是关键。如果@user.valid?
确实导致错误,则会填充@user
上的错误集合。然后,在render :new
完成并重新呈现您的用户表单后,表单将能够通过访问@user.errors
集合来吐出错误消息。否则,就像以前那样,你总是在表单中有一个User.new
对象,它永远不会有任何错误,因为它之前从未用于尝试记录验证。
如何在表单中显示错误是一个偏好问题,稍微超出了本问题的范围。以下是指南:http://guides.rubyonrails.org/active_record_validations.html#displaying-validation-errors-in-views
答案 1 :(得分:3)
我认为这是因为您的form_for
声明,您在每次通话时都在创建新的User实例。
如果您将User.new
移动到控制器并在new
操作失败时呈现create
操作,那么您应该会看到用户在表单字段中输入了值。
以下内容应该有效:
# app/controllers/users_controller.rb
def new
@user = User.new
end
def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
...
else
format.html { render :new }
end
end
end
然后在你看来:
<%= form_for(@user, :url => '/pricing/sign_up') do |f| %>
<%= f.label :email %>
<%= f.email_field :email %>
<% end %>
答案 2 :(得分:2)
表单字段的值由您传递给form_for
的模型驱动,因此在您的情况下,它们将始终为空,因为您传递的是全新的用户对象。
您应该使用在控制器中设置的实例变量;在new
操作中,这将是一个新的User
模型,但在create
操作中,它将是一个通过表单设置属性的模型:
# app/controllers/users_controller.rb
def new
@user = User.new
end
def create
@user = user.create(user_params)
if @user.save
redirect_to user_path(@user)
else
render :new
end
end
然后是以下形式:
<%= form_for(@user, :url => '/pricing/sign_up') do |f| %>
<%= f.label :email %>
<%= f.email_field :email %>
<% end %>