【问题标题】:Retain nested form field value after failed validation验证失败后保留嵌套表单字段值
【发布时间】:2013-06-14 17:47:15
【问题描述】:

我是 Rails 新手,尚未设法解决以下问题。我使用名为“用户”的模型进行身份验证。此模型与另一个名为“company”的模型相关联:

user.rb

  class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable

  belongs_to :company
  accepts_nested_attributes_for :company

  attr_accessible :company_attributes, :email, :password, 
                  :password_confirmation, :remember_me, :company_id

company.rb

  class Company < ActiveRecord::Base

  has_many :users
  attr_accessible :name
  validates :name, :presence => true, :uniqueness => true

注册时,用户同时创建公司和用户:

users_controller.rb

def new
    @user = User.new
    @user.build_company

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @user }
    end
end

def create
  @user = User.new(params[:user])

  respond_to do |format|
    if @user.save
      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render json: @user, status: :created, location: @user 
    else
      format.html { render action: 'new' }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

到目前为止,注册成功,这意味着如果@user.save 为真,则在用户模型和公司模型中分别创建两条记录,并在用户模型的company_id 列中具有正确的关联。

如果@user.save 为假,例如因为用户属性电子邮件验证失败,因为它已经被采用,则呈现一个新视图。正如预期的那样,@user 属性(在本例中为电子邮件)被保留并保留在render action: 'new' 之后的相应表单字段中。但是,公司属性名称的表单字段显示为空白。这是注册页面的视图:

new.html.erb

<%= devise_error_messages! %>
<h2>Sign up</h2>
<%= simple_form_for(resource, :as => resource_name, 
                              :url => registration_path(resource_name),
                              :html => {:class => 'form-horizontal' }) do |f| %>

    <%= f.simple_fields_for :company,  @user.build_company do |builder| %>
        <div><%= builder.label :name, "Company" %><br />
        <%= builder.text_field :name, :autofocus => true, 
                            :placeholder => "Example Company Inc.",
                            :required => true %></div>
    <% end %>

  <div><%= f.label :email %><br />
  <%= f.email_field :email, :placeholder => "example@email.com",  :required => true %></div>

  <div><%= f.label :password %><br />
  <%= f.password_field :password,  :required => true %></div>

  <div><%= f.label :password_confirmation %><br />
  <%= f.password_field :password_confirmation,  :required => true %></div>

  <%= f.submit "Sign up", :class => "btn"%>
<% end %>

<%= render "devise/shared/links" %>

我认为我可能必须在用户创建方法中创建一个实例变量@company,以便可以将表单字段内容保存在 params 哈希中,如下所示:

@company = @user.build_company(params[:company])

不幸的是,这不起作用,到目前为止,我还没有在 stackoverflow 上发布的其他问题中找到解决方案。我期待您的意见,以便我可以继续构建我的第一个应用程序;)

提前感谢您的帮助。

【问题讨论】:

  • 这可能不是原因,但您使用 simple_form_for 资源,但 fields_for :company。尝试更改 fields_for -> simple_fields_for 并检查一下!
  • 嗨,Michal,感谢您的快速回复。我刚刚将f.fields_for更改为f.simple_fields_for。不幸的是,验证失败后,公司名称字段将显示为空白。
  • 将此行 &lt;%= f.simple_fields_for :company, @user.build_company do |builder| %&gt; 更改为 &lt;%= f.simple_fields_for :company do |builder| %&gt;
  • 另外我怀疑设计在这里搞砸了/不幸的是我没有自己的代码与这种关系(只有用户在注册时以一种形式创建了许多其他对象)。也许尝试将其分成两种单独的形式并使用 ajax 就地加载第二个?
  • 更改该行也不能解决问题。但是,公司名称字段不会呈现。因此,我假设 users_controller.rb 中 newmethod 中的 @user.build_company 行不会创建可以保存名称属性的 company 实例。这有意义吗?

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

感谢 Michal 的意见,我重新安排了我的控制器,以便通过关联公司创建用户,而不是相反。相应的公司控制人如下所示:

companies_controller.rb

# GET company/new
def new
    @company = Company.new
    @company.users.build
end

# POST company/
def create
    @company = Company.new(params[:company])

    respond_to do |format|
      if @company.save
        format.html { redirect_to root_path, notice: 'Welcome! Your account has been created successfully. A confirmation link has been sent to your email address.' }
        format.json { render json:  root_path, status: :created, location: @company }
      else
        format.html { render action: "new" }
        format.json { render json: @company.errors, status: :unprocessable_entity }
      end
    end
end

GET 请求嵌套设计用户模型字段的形式如下:

new.html.erb

<h2>Create an account</h2>
<%= simple_form_for( @company, :html => {:class => 'form-horizontal' }) do |f| %>
<%= render 'shared/error_messages', :object => @company %>
    <%= f.input     :name, 
                    :label =>'Company name',
                    :placeholder => "Example Company Inc.",
                    :autofocus => true %>
    <%= f.simple_fields_for :users do |builder| %>
        <%= builder.input   :email, 
                            :placeholder => "example@email.com" %>
        <%= builder.input :password %>
        <%= builder.input :password_confirmation %>
    <% end %>
    <%= f.button    :submit, 'Create account',
                    :class => 'btn'%>
<% end %>
<%= link_to "Sign in", new_session_path(:user) %>

现在,如果验证失败,所有实例属性值都保留在各自的表单字段中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 2012-09-06
    • 2011-08-24
    • 2011-03-07
    • 2012-11-14
    • 1970-01-01
    相关资源
    最近更新 更多