3

我正在构建一个 Rails 3 + 设计,用户注册页面。这将是一个附加页面,不会取代现有的设计注册页面。此页面将包括用户信息和计费信息。

我试图让表单提交,如果表单字段没有保存,让重新加载的页面包含用户以前输入的数据。这是一个片段:

<%= form_for(User.new, :url => '/pricing/sign_up') do |f| %>
    <%= f.label :email %>
    <%= f.email_field :email %>
<% end %>

当表单提交无效数据时。当视图重新呈现时,输入的现有电子邮件不会保留。如何使现有用户的输入持久化,以帮助用户快速纠正错误并提交有效的表单?

4

3 回答 3

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 方法的作用是@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

于 2013-09-01T21:22:07.080 回答
3

我认为这是因为您的form_for声明,您在每次通话时都创建了新的 User 实例。

如果您将 移动到控制器并在操作失败时User.new呈现操作,那么您应该会看到用户在表单字段中输入的值。 newcreate

像下面这样的东西应该可以工作:

# 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 %>
于 2013-09-01T21:20:43.990 回答
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 %>
于 2013-09-01T21:25:33.017 回答