Ruby on rails 验证失败后保留嵌套表单字段值
我是rails新手,尚未解决以下问题。我使用Desive对名为“用户”的模型进行身份验证。此模型与另一个名为“公司”的模型关联: user.rbRuby on rails 验证失败后保留嵌套表单字段值,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我是rails新手,尚未解决以下问题。我使用Desive对名为“用户”的模型进行身份验证。此模型与另一个名为“公司”的模型关联: user.rb class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable belongs_
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
class Company < ActiveRecord::Base
has_many :users
attr_accessible :name
validates :name, :presence => true, :uniqueness => true
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
<%= 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" %>
# 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
<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) %>
到目前为止,注册是有效的,这意味着如果@user.save
为真,则在用户和公司模型中分别创建两条记录,并在用户模型的公司id
列中创建正确的关联
如果@user.save
为false,例如,因为用户属性电子邮件的验证失败,因为它已经被获取,则会呈现一个新视图。正如所料,@user
属性(在本例中为电子邮件)将保留,并在呈现操作:“新建”之后保留在相应的表单字段中。但是,公司属性名称的表单字段显示为空。这是注册页面的视图:
new.html.erb
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
class Company < ActiveRecord::Base
has_many :users
attr_accessible :name
validates :name, :presence => true, :uniqueness => true
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
<%= 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" %>
# 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
<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) %>
不幸的是,这不起作用,到目前为止,我还没有在stackoverflow上发布的其他问题中找到解决方案。我期待您的输入,以便我可以继续构建我的第一个应用;)
提前感谢您的帮助。多亏了Michal的帮助,我重新安排了我的控制器,以便通过关联公司创建用户,而不是反过来创建用户。相应的公司控制器如下所示:
@company = @user.build_company(params[:company])
公司\u controller.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
class Company < ActiveRecord::Base
has_many :users
attr_accessible :name
validates :name, :presence => true, :uniqueness => true
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
<%= 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" %>
# 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
<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) %>
GET请求的表单嵌套Desive用户模型字段,如下所示:
new.html.erb
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
class Company < ActiveRecord::Base
has_many :users
attr_accessible :name
validates :name, :presence => true, :uniqueness => true
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
<%= 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" %>
# 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
<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) %>
创建一个帐户
{:class=>'form horizontal'})do | f |%>
@公司%>
“公司名称”,
:占位符=>“示例公司”,
:自动对焦=>true%>
"example@email.com" %>
'btn'>
现在,如果验证失败,所有实例属性值将保留在各自的表单字段中。这可能不是原因,但您使用简单表单作为资源,而字段作为:company。尝试changind fields\u for->simple\u fields\u for并查看它!嘿,迈克,谢谢你的快速回复。我刚刚将
的f.fields\u更改为
的f.simple\u fields\u。不幸的是,验证失败后,“公司名称”字段将变为空白。将此行
更改为
。此外,我怀疑Deavise在这里搞乱了一些东西/不幸的是,我没有自己的代码与这种关系(只有用户在注册时以一种形式创建了许多其他对象)。也许可以尝试将其分为两个单独的表单,并使用ajax加载第二个表单?更改该行也不能解决问题。但是,“公司名称”字段将不会呈现。因此,我假设users\u controller.rb中我的new
方法中的@user.build\u company
行没有创建可以保存name属性的company实例。这有意义吗?