Ruby on rails 如何将验证错误消息传递给其他控制器中的方法?

Ruby on rails 如何将验证错误消息传递给其他控制器中的方法?,ruby-on-rails,Ruby On Rails,我刚刚启动了一个rails 3应用程序,它有一个父模型和一个子模型(父模型有很多子模型) 我正在尝试进行设置,以便在创建新的父级之后,用户可以执行该父级的显示操作(/parent/id)。在这个视图中,我包含了显示任何子级的部分和创建新子级的表单。创建新子级后,用户将重定向到新子级将出现的父级的“显示”操作。这一切都按预期进行 但是,如果我尝试验证新子窗体中的字段,则出现的任何错误消息都不会出现在窗体中(视图中的必要行在那里并且是正确的-从生成的scaffold代码中剪切和粘贴)。是否有一种方法

我刚刚启动了一个rails 3应用程序,它有一个父模型和一个子模型(父模型有很多子模型)

我正在尝试进行设置,以便在创建新的父级之后,用户可以执行该父级的显示操作(/parent/id)。在这个视图中,我包含了显示任何子级的部分和创建新子级的表单。创建新子级后,用户将重定向到新子级将出现的父级的“显示”操作。这一切都按预期进行

但是,如果我尝试验证新子窗体中的字段,则出现的任何错误消息都不会出现在窗体中(视图中的必要行在那里并且是正确的-从生成的scaffold代码中剪切和粘贴)。是否有一种方法可以成功地将子级的这些错误消息传递给父级显示操作

以下是相关代码的片段

从我的父控制器:

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
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
从我的孩子控制器:

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
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

如果子级无效,则只呈现父级的“显示”页面,该怎么办

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
您可能还希望对板条箱操作执行类似的操作,以确保父级存在

@parent = Parent.find(params[:parent][:parent_id])
@child  = @parent.children.build(params[:parent])

这样,您的用户就不能创建无效的子级,并且您有父级来再次呈现显示页面。你不应该给用户设置自己的父id的能力

好吧,我自己解决了这个问题。谢谢Terw的回答。除了由于缺少重定向而给出错误的URL之外,它还能工作

只需通过会话散列传递错误,然后将它们添加到父控制器中的子模型中

我发布代码是因为我找不到其他类似的例子。也许有一种更简单的方法,但到目前为止,这种方法非常有效。如果有人认为我疯了,请解释

在我的孩子控制器中

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
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
在我的父母控制器里

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
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

谢谢,这会显示错误消息,这是一个开始。(四处阅读-渲染“父/显示”是正确的方法)。问题是,由于没有重定向,显示的URL无效。这是一个小得多的问题,但仍然不够理想。感谢您提供有关先加载父对象的提示(尽管恶意用户仍然可以轻松发送有效但不正确的父对象id来附加子对象)。此外,它应该是Parent.find(params[:child][:Parent_id])和.build(params[:child])。不是想学究气,只是想帮助其他读到这篇文章的人。