I am just starting a rails 3 app that has a parent model and a child model (parent has_many :children).
我刚刚开始使用rails 3应用程序,它具有父模型和子模型(父has_many:children)。
I am trying to set things up so that after creating a new parent the user is taken to the show action of that parent (/parent/id). In this view I have included partials to show any children and a form to create a new child. After creating a new child the user is redirected to the show action for the parent where the new child will appear. This all works as intended.
我正在尝试进行设置,以便在创建新父级之后,用户将被带到该父级的显示操作(/ parent / id)。在这个视图中,我包括部分显示任何孩子和表单来创建一个新孩子。创建新子项后,用户将被重定向到将显示新子项的父项的show操作。这一切都按预期工作。
However, if I try to validate fields in the new child form any error messages that occur are not appearing in the form (the necessary lines in the view are there and are correct - cut and pasted from generated scaffold code). Is there a way of passing these error messages for the child successfully to the parent show action?
但是,如果我尝试验证新子窗体中的字段,则出现的任何错误消息都不会出现在窗体中(视图中的必要行是正确的 - 从生成的脚手架代码中剪切并粘贴)。有没有办法将孩子的这些错误消息成功传递给父节目动作?
Here are snippets of relevant code;
以下是相关代码的片段;
From my parent controller:
从我的父控制器:
def show
@parent = Parent.find(params[:id])
@child = @parent.children.new
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @admission }
end
end
From my child controller:
从我的孩子控制器:
def create
@child = Child.new(params[:parent])
respond_to do |format|
if @child.save
format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') }
#This works as intended
format.xml { render :xml => @child, :status => :created, :location => @child }
else
format.html { redirect_to parent_path(params[:child][:patient_id]) }
#This redirects where I want it to go when validation fails but error messages are lost
format.xml { render :xml => @child.errors, :status => :unprocessable_entity }
end
end
end
2 个解决方案
#1
11
Alright, I solved this myself. Thanks for Terw's answer though. It works apart from giving the wrong URL because of the lack of redirect.
好吧,我自己解决了这个问题。感谢Terw的回答。由于缺少重定向,它与提供错误的URL不同。
It was simply a matter of passing the errors via the session hash and then adding them to the child model in the parent controller.
这只是通过会话哈希传递错误然后将它们添加到父控制器中的子模型的问题。
I'm posting the code because I couldn't find any other examples of this out there. Perhaps there's a simpler way but this works perfectly so far. If anyone thinks I'm crazy then please explain.
我发布了代码,因为我找不到任何其他的例子。也许有一种更简单的方法,但到目前为止这种方法完美无缺。如果有人认为我疯了,请解释。
In my child controller
在我的孩子控制器
def create
@parent = Parent.find(params[:child][:parent_id])
@child = @parent.child.build(params[:child])
respond_to do |format|
if @child.save
format.html { redirect_to(parent_path(params[:admission][:parent_id]), :notice => 'Child was successfully created.') }
format.xml { render :xml => @child, :status => :created, :location => @child }
else
if @child.errors.any?
session[:child_errors] = @child.errors
end
format.html { redirect_to(parent_path(params[:child][:parent_id])) }
format.xml { render :xml => @child.errors, :status => :unprocessable_entity }
end
end
end
And in my parent controller
在我的父控制器中
def show
@parent = Parent.find(params[:id])
@child = @parent.children.new
if session[:child_errors]
session[:child_errors].each {|error, error_message| @child.errors.add error, error_message}
session.delete :child_errors
end
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @parent }
end
end
#2
1
What if you just render the parent's show page if the child is invalid?
如果孩子无效,您只是渲染父母的节目页面怎么办?
def create
@child = Child.new(params[:parent])
respond_to do |format|
if @child.save
format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') }
#This works as intended
format.xml { render :xml => @child, :status => :created, :location => @child }
else
format.html { render :controller => :parent, :action => :show }
# Display the parent's show page to display the errors
format.xml { render :xml => @child.errors, :status => :unprocessable_entity }
end
end
end
You might also want to do something like this for the crate action to make sure the parent exists.
您可能还希望对crate操作执行类似的操作以确保父项存在。
@parent = Parent.find(params[:parent][:parent_id])
@child = @parent.children.build(params[:parent])
Then your users can't create an invalid child, and you have the parent to render the show page again. You shouldn't give the users the ability to set the parent_id them selfes.
然后,您的用户无法创建无效的子项,并且您有父级可以再次呈现该显示页面。您不应该让用户能够将parent_id设置为selfes。
#1
11
Alright, I solved this myself. Thanks for Terw's answer though. It works apart from giving the wrong URL because of the lack of redirect.
好吧,我自己解决了这个问题。感谢Terw的回答。由于缺少重定向,它与提供错误的URL不同。
It was simply a matter of passing the errors via the session hash and then adding them to the child model in the parent controller.
这只是通过会话哈希传递错误然后将它们添加到父控制器中的子模型的问题。
I'm posting the code because I couldn't find any other examples of this out there. Perhaps there's a simpler way but this works perfectly so far. If anyone thinks I'm crazy then please explain.
我发布了代码,因为我找不到任何其他的例子。也许有一种更简单的方法,但到目前为止这种方法完美无缺。如果有人认为我疯了,请解释。
In my child controller
在我的孩子控制器
def create
@parent = Parent.find(params[:child][:parent_id])
@child = @parent.child.build(params[:child])
respond_to do |format|
if @child.save
format.html { redirect_to(parent_path(params[:admission][:parent_id]), :notice => 'Child was successfully created.') }
format.xml { render :xml => @child, :status => :created, :location => @child }
else
if @child.errors.any?
session[:child_errors] = @child.errors
end
format.html { redirect_to(parent_path(params[:child][:parent_id])) }
format.xml { render :xml => @child.errors, :status => :unprocessable_entity }
end
end
end
And in my parent controller
在我的父控制器中
def show
@parent = Parent.find(params[:id])
@child = @parent.children.new
if session[:child_errors]
session[:child_errors].each {|error, error_message| @child.errors.add error, error_message}
session.delete :child_errors
end
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @parent }
end
end
#2
1
What if you just render the parent's show page if the child is invalid?
如果孩子无效,您只是渲染父母的节目页面怎么办?
def create
@child = Child.new(params[:parent])
respond_to do |format|
if @child.save
format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') }
#This works as intended
format.xml { render :xml => @child, :status => :created, :location => @child }
else
format.html { render :controller => :parent, :action => :show }
# Display the parent's show page to display the errors
format.xml { render :xml => @child.errors, :status => :unprocessable_entity }
end
end
end
You might also want to do something like this for the crate action to make sure the parent exists.
您可能还希望对crate操作执行类似的操作以确保父项存在。
@parent = Parent.find(params[:parent][:parent_id])
@child = @parent.children.build(params[:parent])
Then your users can't create an invalid child, and you have the parent to render the show page again. You shouldn't give the users the ability to set the parent_id them selfes.
然后,您的用户无法创建无效的子项,并且您有父级可以再次呈现该显示页面。您不应该让用户能够将parent_id设置为selfes。