form_for 및 중첩 리소스에 대해 두 부분으로 된 질문이 있습니다. 내가 블로그 엔진을 작성 중이고 기사에 댓글을 연결하고 싶다고 가정 해 보겠습니다. 다음과 같이 중첩 된 리소스를 정의했습니다.
map.resources :articles do |articles|
articles.resources :comments
end
댓글 양식은 다음과 같이 기사 자체 아래에있는 기사의 show.html.erb보기에 있습니다.
<%= render :partial => "articles/article" %>
<% form_for([ :article, @comment]) do |f| %>
<%= f.text_area :text %>
<%= submit_tag "Submit" %>
<% end %>
이것은 오류, “Called id for nil, 이것은 실수로 등이 될 것입니다.” 나는 또한 시도했다
<% form_for @article, @comment do |f| %>
올바르게 렌더링되지만 f.text_area를 댓글 대신 기사의 ‘텍스트’필드와 관련시키고 해당 텍스트 영역의 article.text 속성에 대한 html을 표시합니다. 그래서 나는 이것도 잘못된 것 같습니다. 내가 원하는 것은 ‘제출’이 CommentsController에 대한 생성 작업을 호출하는 양식입니다. 예를 들어 / articles / 1 / comments에 대한 게시 요청과 같이 params에 article_id가 있습니다.
내 질문의 두 번째 부분은 시작하는 주석 인스턴스를 만드는 가장 좋은 방법은 무엇입니까? ArticlesController의 show 작업에서 @comment를 만들고 있으므로 주석 개체는 form_for 도우미의 범위에 있습니다. 그런 다음 CommentsController의 생성 작업에서 form_for에서 전달 된 매개 변수를 사용하여 새 @comment를 생성합니다.
감사!
답변
Travis R이 맞습니다. (나는 당신을 찬성 할 수 있으면 좋겠어요.) 방금이 일을 직접 했어요. 다음 경로로 :
resources :articles do
resources :comments
end
다음과 같은 경로를 얻습니다.
/articles/42
/articles/42/comments/99
컨트롤러로 라우팅
app/controllers/articles_controller.rb
app/controllers/comments_controller.rb
http://guides.rubyonrails.org/routing.html#nested-resources 에서 말하는 것처럼 특별한 네임 스페이스가 없습니다.
그러나 부분과 형태는 까다로워집니다. 대괄호에 유의하십시오.
<%= form_for [@article, @comment] do |f| %>
가장 중요한 것은 URI를 원한다면 다음과 같은 것이 필요할 수 있습니다.
article_comment_path(@article, @comment)
또는 :
[@article, @comment]
http://edgeguides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects에 설명 된대로
예를 들어, comment_item
반복을 위해 제공된 부분 컬렉션 내부 에서
<%= link_to "delete", article_comment_path(@article, comment_item),
:method => :delete, :confirm => "Really?" %>
jamuraa가 말하는 것은 Article의 맥락에서 작동 할 수 있지만 다른 다양한 방식으로는 작동하지 않았습니다.
중첩 된 리소스와 관련된 많은 토론이 있습니다. 예 : http://weblog.jamisbuck.org/2007/2/5/nesting-resources
흥미롭게도 저는 대부분의 사람들의 단위 테스트가 실제로 모든 경로를 테스트하는 것은 아니라는 것을 방금 배웠습니다. 사람들이 jamisbuck의 제안을 따를 때 중첩 된 리소스를 얻는 두 가지 방법으로 끝납니다. 그들의 단위 테스트는 일반적으로 가장 간단한 것을 얻거나 게시합니다.
# POST /comments
post :create, :comment => {:article_id=>42, ...}
선호하는 경로를 테스트하려면 다음과 같이해야합니다.
# POST /articles/42/comments
post :create, :article_id => 42, :comment => {...}
내가 이것을 전환했을 때 내 단위 테스트가 실패하기 시작했기 때문에 이것을 배웠습니다.
resources :comments
resources :articles do
resources :comments
end
이에:
resources :comments, :only => [:destroy, :show, :edit, :update]
resources :articles do
resources :comments, :only => [:create, :index, :new]
end
중복 경로가 있고 몇 가지 단위 테스트를 놓치는 것은 괜찮다고 생각합니다. (왜 테스트해야합니까? 사용자가 중복을 보지 않더라도 양식에서 암시 적으로 또는 명명 된 경로를 통해 참조 할 수 있기 때문입니다.) 그래도 불필요한 중복을 최소화하려면 다음을 권장합니다.
resources :comments
resources :articles do
resources :comments, :only => [:create, :index, :new]
end
긴 답변에 대해 죄송합니다. 미묘함을 아는 사람은 많지 않은 것 같습니다.
답변
controller : @post
와 @comment
포스트에 대해 두 객체가 모두 생성되었는지 확인하십시오. 예 :
@post = Post.find params[:post_id]
@comment = Comment.new(:post=>@post)
그런 다음보기 :
<%= form_for([@post, @comment]) do |f| %>
위와 같이 쉼표로 구분 된 것이 아니라 form_for에 배열을 명시 적으로 정의해야합니다.
답변
양식에서 특별한 일을 할 필요가 없습니다. show 작업에서 올바르게 주석을 작성하면됩니다.
class ArticlesController < ActionController::Base
....
def show
@article = Article.find(params[:id])
@new_comment = @article.comments.build
end
....
end
그런 다음 기사보기에서 양식을 작성하십시오.
<% form_for @new_comment do |f| %>
<%= f.text_area :text %>
<%= f.submit "Post Comment" %>
<% end %>
기본적으로,이 댓글은 갈 것 create
의 행동 CommentsController
이 다음 아마 데려 가고 싶다는 것, redirect :back
받는 당신이 그렇게있는 거 라우팅 뒷면에 Article
페이지.