2014-01-02 5 views
0

Я делаю онлайн-учебник, которому было поручено реализовать ресурс комментариев, который вложен в почтовый ресурс, который, в свою очередь, находится под тематическим ресурсом. Я выяснил все шаги упражнения, за исключением того, что форма «комментариев создала» отображалась в сообщении # show. Я пытался несколько часов исправлять его, но продолжаю получать следующую ошибку: undefined method "model_name" for NilClass:Class. Я понятия не имею, о чем идет речь model_name, и в отчаянии я даже посмотрел код учебника на GitHub, но я все еще не вижу, где я делаю ошибку.Форма для вложенного ресурса: неопределенный метод `model_name 'для NilClass: класс

Моя форма в частичной и ошибки указывает на первой линии, поэтому я буду вставлять код здесь первый:

<%= form_for [topic, post, comment] do |f| %> 
    <div class="controls"> 
     <%= f.text_area :body, rows: 8 %> 
    </div> 
    <div class="control-group"> 
    <div class="controls"> 
     <%= f.submit "Add Comment", class: 'btn' %> 
    </div> 
    </div> 
<% end %> 

я выложу свои маршруты, так что вы можете увидеть вложенности:

X::Application.routes.draw do 

    devise_for :users 

    resources :topics do 
    resources :posts, except: [:index] do 
     resources :comments, only: [:create] 
    end 
    end 

    match "about" => 'welcome#about', via: :get 

    root to: 'welcome#index' 

end 

Вот мой Комментарии контроллер:

class CommentsController < ApplicationController 

    def new 
    end 

    def create 
    @topic = Topic.find(params[:topic_id]) 
    @post = Post.find(params[:post_id]) 

    @comment = current_user.comments.build(params[:comment]) 
    @comment.post = @post 


    if @comment.save 
     flash[:notice] = "Comment was saved." 
     redirect_to @post 
    else 
     flash[:error] = "Error! Try again." 
     render :new 
    end 
    end 
end 

Вот мой пост # показать вид (форма должна быть оказание внизу):

<h1><%= markdown @post.title %></h1> 

<div class="row"> 
    <div class="span8"> 
    <small> 
     <%= image_tag(@post.user.avatar.tiny.url) if @post.user.avatar? %> 
     submitted <%= time_ago_in_words(@post.created_at) %> ago by 
     <%= @post.user.name %> 
    </small> 
    <br><br>  
    <p><%= image_tag(@post.image.url) if @post.image? %></p> 
    <p><%= markdown @post.body %></p> 
    </div> 
    <div class="span2"> 
    <% if can? :edit, @post %> 
     <%= link_to "Edit Post", edit_topic_post_path(@topic,@post), class: 'btn btn-small' %> 
    <% end %> 
    </div> 
</div> 
<br><br> 
<h4>Comments</h4> 
<%= render @comments %> 
<br> 
<%= render :template => "/comments/_form.html.erb", locals: { topic: @topic, post: @post, comment: @comment } %> 

Я был бы так благодарен, если бы кто-нибудь мог помочь мне с этой проблемой. И дайте мне знать, если есть информация, которую я должен добавить. Спасибо!

ответ

0

Как правило, из того, что я прочитал, не рекомендуется использовать 3-уровневые вложенные ресурсы. Не могли бы вы ссылаться на учебник, за которым вы следуете?

В любом случае, я бы предложил использовать мелкие на ваших маршрутах.

resources :topics, shallow: true do 
    resources :posts, except: [:index], shallow: true do 
    resources :comments, only: [:create] 
    end 
end 

Предоставьте вам следующие ресурсы, которые в свою очередь облегчат создание правильных форм в вашем представлении.

post_comments POST /posts/:post_id/comments(.:format) comments#create 
    topic_posts POST /topics/:topic_id/posts(.:format)  posts#create 
new_topic_post GET /topics/:topic_id/posts/new(.:format) posts#new 
    edit_post GET /posts/:id/edit(.:format)    posts#edit 
      post GET /posts/:id(.:format)     posts#show 
       PATCH /posts/:id(.:format)     posts#update 
       PUT /posts/:id(.:format)     posts#update 
       DELETE /posts/:id(.:format)     posts#destroy 
     topics GET /topics(.:format)      topics#index 
       POST /topics(.:format)      topics#create 
    new_topic GET /topics/new(.:format)     topics#new 
    edit_topic GET /topics/:id/edit(.:format)   topics#edit 
     topic GET /topics/:id(.:format)     topics#show 
       PATCH /topics/:id(.:format)     topics#update 
       PUT /topics/:id(.:format)     topics#update 
       DELETE /topics/:id(.:format)     topics#destroy 

Теперь вам нужно только отправить post_id в форму комментариев. Подробнее here Я не много работал с 3-мя уровнями гнездования, но это должно дать вам представление о том, как вы могли бы сделать это проще для себя.

EDIT: В действии create вы должны создать комментарий, используя @post, а затем установить для пользователя current_user.

def create 

    @post = Post.find(params[:post_id]) 

    @comment = @post.comments.build(params[:comment]) 
    @comment.user = current_user 


    if @comment.save 
     flash[:notice] = "Comment was saved." 
     redirect_to @post 
    else 
     flash[:error] = "Error! Try again." 
     render :new 
    end 
    end 

И теперь нет необходимости в @topic

<%= render :template => "/comments/_form.html.erb", locals: { post: @post, comment: @comment } %> 
+0

Итак, если бы я использовал эти мелкие варианты, я бы использовал <% = form_for [post, comment] do | f | %> и удалить объявления переменных темы из CommentController? – sixty4bit

+0

Да, правильно, я отредактировал свой ответ выше. – Pierre

+0

Ну, я чувствую себя довольно глупо, но, оказывается, все, что мне нужно было сделать, это добавить «@comment = Comment.new» к действию «show» PostController. Это было определено только в действии «create» CommentController. – sixty4bit

0

Add '@comment = Comment.new' к "шоу" действия PostController. Он был определен только в действии «create» CommentController.

Смежные вопросы