5

Đã có nhiều câu hỏi về điều này, nhưng không có câu hỏi nào trong số này có vẻ hữu ích. Và vâng, tôi đã xem this rails cast.Xác thực mô hình lồng nhau - lỗi không hiển thị

Tôi có một tác giả người có nhiều sách, như vậy:

Tác giả:

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 

Sách:

class Book < ActiveRecord::Base 
    attr_accessible :name, :year 
    belongs_to :author 

    validates :name, :year, presence: true 
    validates :year, numericality: { only_integer: true, less_than_or_equal_to: Time.now.year } 
end 

Tôi tạo ra các hình thức sau đây để thêm một cuốn sách để một tác giả trong các tác giả # hiển thị:

<%= form_for([@author, @book], html: { class: "well" }) do |f| %> 
<% if @book.errors.any? %> 
    <div class="alert alert-block"> 
     <ul> 
      <% @author.errors.full_messages.each do |msg| %> 
       <li><%= msg %></li> 
      <% end %> 
     </ul> 
    </div> 
<% end %> 
#labels and buttons... 
<% end %> 

... với phương pháp authors_controller sau:

def show 
    @author = Author.find(params[:id]) 
    @book = @author.books.build 
end 

... và phương pháp books_controller sau:

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 

tôi dường như không thể tìm ra lý do tại sao các hình thức không hiển thị bất kỳ thông báo lỗi. Tôi theo ví dụ từ railscasts, nơi họ nói rằng nên có một biến dụ của các cuốn sách trong các hình thức thay vì @ author.books.build, vì vậy tôi đặt sau trong bộ điều khiển và @book trong các hình thức - vẫn không có avail.

Cảm ơn bạn đã trợ giúp!

Trả lời

8

Hãy xem qua nó.

Bạn nộp tạo, và đó vào tạo bạn hành động

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 

(Side lưu ý, những gì nếu @author không được tìm thấy. Bạn chưa xử lý trường hợp đó.)

Bây giờ, các Tác giả được tìm thấy, nhưng @ author.books.create không thành công (trả về false), vì vậy bạn kết xuất hành động hiển thị.

Điều này sử dụng mẫu chương trình, nhưng không gọi mã chương trình hành động. (Lưu ý phụ, có thể trang mới sẽ là lựa chọn tốt hơn, vì vậy người dùng có thể thử tạo lại.)

Tại thời điểm này, @author được khởi tạo với Tác giả bạn tìm thấy, chứ không phải @book. Vì vậy, @book, nếu được gọi sẽ là số không.

mẫu chương trình của bạn không

if @book.errors.any? 

đó sẽ không là sự thật, vì vậy phần còn lại của mẫu bên trong nếu sẽ bị bỏ qua. Đó là lý do tại sao không có lỗi.

Bạn không cần form_for để hiển thị thông báo lỗi. Nếu bạn chuyển sang sử dụng mẫu mới, thì sẽ có một biểu mẫu để thử lại.

Vì vậy, hãy chuyển sang hiển thị mới.

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 

mẫu mới của bạn sẽ

<% 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 %> 
+0

Cảm ơn bạn đã trả lời chi tiết này rồi! Tôi không có phương pháp mới trong bộ điều khiển sách - biểu mẫu cho sách mới được hiển thị khi tác giả được hiển thị. Ngoài ra, khi tôi thay đổi phương thứC# tạo sách như bạn đã đề xuất, tôi nhận được lỗi định tuyến nói rằng nó không thể tìm thấy phương thức chỉnh sửa. Tôi cần làm gì khác để sửa lỗi này? – weltschmerz

+0

Tôi quên thay đổi chuyển hướng thành: mới. Thiết kế RESTful chuẩn (không nhất thiết phải là thiết kế tốt nhất) như tôi đã mô tả, nơi sẽ có một trang mới cho sách. Nếu bạn muốn làm cho nó hoạt động khác nhau, hãy cố gắng hiểu những gì đã xảy ra và sửa nó theo cách bạn muốn. –

1

Trong điều khiển Sách /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 

Nếu tác giả không phải là chuyển hướng mặt để trang tác giả chỉ số với thông báo lỗi không làm cho hình thức mới như bạn sẽ không thể xây dựng các hình thức sách như tác giả là không.

Và trong sách của mình hình thức mới, bạn có thể có các lỗi được liệt kê cho sách

/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 %> 
Các vấn đề liên quan