Ruby on rails 嵌套模型验证-错误不';不显示
关于这一点有很多问题,但似乎都没有帮助。是的,我看过 我有一位作家,他有很多书,比如: 作者:Ruby on rails 嵌套模型验证-错误不';不显示,ruby-on-rails,ruby,model-view-controller,validation,nested-forms,Ruby On Rails,Ruby,Model View Controller,Validation,Nested Forms,关于这一点有很多问题,但似乎都没有帮助。是的,我看过 我有一位作家,他有很多书,比如: 作者: class Author < ActiveRecord::Base attr_accessible :name has_many :books, dependent: :destroy accepts_nested_attributes_for :books, allow_destroy: true validates :name, presence: true vali
class Author < ActiveRecord::Base
attr_accessible :name
has_many :books, dependent: :destroy
accepts_nested_attributes_for :books, allow_destroy: true
validates :name, presence: true
validates :name, length: { minimum: 3 }
end
…以及以下方法:
def show
@author = Author.find(params[:id])
@book = @author.books.build
end
def create
@author = Author.find(params[:author_id])
if @author.books.create(params[:book])
redirect_to author_path(@author)
else
render action: :show
end
end
我似乎无法理解表单为什么不显示任何错误消息。我遵循railscasts的例子,他们说表单中应该有books的实例变量,而不是@author.books.build,所以我将后者放在控制器中,将@book放在表单中,但仍然没有用
谢谢你的帮助 让我们一步一步来
您提交了create,然后进入create操作
def create
@author = Author.find(params[:author_id])
if @author.books.create(params[:book])
redirect_to author_path(@author)
else
render action: :show
end
end
(旁注,如果找不到@author怎么办?你不是在处理这个案子。)
现在,找到了Author,但是@Author.books.create失败(返回false),因此呈现show操作
这将使用显示模板,但不调用显示操作代码。(请注意,新页面可能是更好的选择,因此用户可以尝试再次创建。)
此时@author被实例化为您找到的作者,但不是@book。所以@book,如果调用,将为零
您的显示模板不支持
if @book.errors.any?
这将不是真的,因此将跳过if中的其余模板。这就是为什么没有错误
您不需要表单_来显示错误消息。如果您切换到使用新模板,则将有一个表单重试
因此,让我们切换到渲染新对象
Class BooksController < ApplicationController
def new
@author = Author.find(params[:author_id])
@book = @author.books.build
end
def create
@author = Author.find(params[:author_id])
@book = @author.books.build(params[:book])
if @author.save
redirect_to author_path(@author)
else
render action: :new
end
end
Class BooksController
您的新模板将被删除
<% if @author.errors.any? %>
<div class="alert alert-block">
<ul>
<% @author.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% if @book.errors.any? %>
<div class="alert alert-block">
<ul>
<% @book.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form_for([@author, @book], html: { class: "well" }) do |f| %>
#labels and buttons...
<% end %>
#标签和按钮。。。
在图书控制器中
/books_controller.rb
def new
@author = Author.find_by_id(params[:author_id])
@book = @author.books.build
end
def create
@author = Author.find_by_id(params[:author_id])
if @author
@book = @author.books.build(params[:book])
if @book.save
flash[:notice] = "Book saved successfully"
redirect_to author_path(@author)
else
render :new
end
else
flash[:notice] = "Sorry no author found"
redirect_to author_path
end
end
如果作者不存在,请重定向到带有错误消息的作者索引页,不要呈现新表单,因为由于作者为零,您将无法构建图书表单
在您的图书新表单中,您可以为图书列出错误
/books/new.html.erb
<% if @book.errors.any? %>
<div class="alert alert-block">
<ul>
<% @books.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
谢谢您的详细回答!我在books控制器中没有新方法-当显示作者时,将显示新书的表单。另外,当我按照您的建议更改books#create方法时,我收到一个路由错误,表示找不到编辑方法。要解决这个问题,我需要做哪些不同的操作?我忘记将重定向更改为:new。正如我所描述的,标准的RESTful设计(不一定是最好的设计)将为书籍提供一个新的页面。如果你想让它以不同的方式工作,试着去理解出了什么问题,并按照你想要的方式来修复它。
def new
@author = Author.find_by_id(params[:author_id])
@book = @author.books.build
end
def create
@author = Author.find_by_id(params[:author_id])
if @author
@book = @author.books.build(params[:book])
if @book.save
flash[:notice] = "Book saved successfully"
redirect_to author_path(@author)
else
render :new
end
else
flash[:notice] = "Sorry no author found"
redirect_to author_path
end
end
<% if @book.errors.any? %>
<div class="alert alert-block">
<ul>
<% @books.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>