5

많은 질문이 있지만 도움이되지는 않습니다. 그리고 예, 나는 this rails cast을 보았다.중첩 모델 유효성 검사 - 오류가 표시되지 않습니다.

나는 많은 책과 같이이있는 저자 :

저자 :

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 

내가 저자에 책을 추가하려면 다음 양식을 작성 : 책이
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 

저자 : # show :

<%= 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 %> 
다음 authors_controller 방법으로

... :

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

... 다음과 같은 books_controller 방법 : I 양식이 오류 메시지를 표시하지 않는 이유를 알아낼 수 없습니다

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의 예제를 따라 @ author.books.build 대신에 폼의 인스턴스 변수가 있어야한다고 말했기 때문에 나는 후자를 컨트롤러에두고 @book을 폼에 넣어 뒀다.

도움 주셔서 감사합니다.

답변

8

단계별로 살펴 보겠습니다.

당신은 생성 제출, 그것은 당신의 행동을

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.books.create는 실패 (false를 반환)하므로 show 액션을 렌더링합니다.

이것은 쇼 템플릿을 사용하지만 표시 작업 코드를 호출하지 않습니다. (사이드 노트, 새로운 페이지가 더 좋은 선택이 될 수 있으므로 사용자가 다시 만들려고 할 수 있습니다.)

이 시점에서 @author은 발견 한 작성자와 인스턴스화되지만 @book은 인스턴스화되지 않습니다. 그래서 @book은 불려지면 무효가됩니다.

쇼 템플릿 사실이되지 않습니다

if @book.errors.any? 

을한다, 그래서 내부 템플릿의 나머지는 생략됩니다. 그래서 오류가없는 것입니다.

오류 메시지를 표시하는 데 form_for가 필요하지 않습니다. 새 템플릿을 사용하도록 전환하면 다시 시도 할 양식이 생깁니다.

그래서 새로운 렌더링으로 전환 해 보겠습니다.

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 

새 템플릿 북 컨트롤러에서

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

이미이 자세한 답변을 주셔서 감사합니다 책

/books/new.html.erb을위한 새로운 형태의 나열했습니다 수 있습니다! 책 컨트롤러에 새로운 방법이 없습니다. 저자가 표시되면 새 책의 양식이 표시됩니다. 또한 books # create 메서드를 제안대로 변경하면 편집 메서드를 찾을 수 없다는 라우팅 오류가 발생합니다. 이 문제를 해결하려면 어떻게해야합니까? – weltschmerz

+0

리디렉션을 new : new로 변경하는 것을 잊었습니다. 표준 RESTful 디자인 (반드시 최고의 디자인은 아님)은 필자가 설명한 것처럼 책을위한 새로운 페이지가있을 것이다. 다른 방식으로 작동 시키려면 잘못된 것이 무엇인지 이해하고 원하는 방식으로 수정하십시오. –

1

될 것 /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 

저자는 오류 메시지와 함께 저자의 인덱스 페이지에 존재 리디렉션가 아닌 경우는 렌더링하지 말아 작성자로 서적 양식을 작성할 수 없으므로 새로운 양식이 없습니다.

그리고 당신의 책

당신은 오류가

<% if @book.errors.any? %> 
    <div class="alert alert-block"> 
     <ul> 
     <% @books.errors.full_messages.each do |msg| %> 
      <li><%= msg %></li> 
     <% end %> 
    </ul> 
    </div> 
<% end %> 
관련 문제