Jseb
Jseb

Reputation: 1934

Deep nested resources rails

I understand deep nested resource should not be adopted, however i do not know how to convert it properly to a 1 level nested resources. If clean tutorial exists show me the tutorial and I will learn it. If not Then please help with my problem. Here my route.rb

resources :article do
  resources :picture
  resources :comments do
    resources :repcomments
  end
end
resources :reports

I can do article, picture, comments but not to sure how to approach the third level of reports. The idea comes that an article can have comments and where the comment could be reported to management. Everythings plays in the article#show pages and here the controller

  def show
    @art = Article.find(params[:id])
    @comments = @art.comments.find(:all, :order => 'created_at DESC')
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @art }
    end
  end

Here the view form in article#show

<%= @art.title %>
<%= @art.content %>
Comment
<%= form_for [@art, current_customer.comments.new] do |f| %>
  <%= f.text_area :description %><br />
  <%= f.submit "Add Comment" %>
<% end %>
# End of form comments
<% @comments.each do |comment| %>
  <%= comment.description %>
  <div>Report</div>
  <%= form_for [@art, comment, repcomments.new] do |f| %>
    <%= f.text_area :body %><br />
    <%= f.submit "Report it" %>
  <% end %> 
<% end %>

I am getting a no define method and not to sure how to approach it. Thanks in advance

Here the route file

 article_comment_repcomments GET    /articles/:article_id/comments/:comment_id/repcomments(.:format)          repcomments#index
                              POST   /articles/:article_id/comments/:comment_id/repcomments(.:format)          repcomments#create
 new_article_comment_repcomment GET    /articles/:article_id/comments/:comment_id/repcomments/new(.:format)      repcomments#new
edit_article_comment_repcomment GET    /articles/:article_id/comments/:comment_id/repcomments/:id/edit(.:format) repcomments#edit
     article_comment_repcomment GET    /articles/:article_id/comments/:comment_id/repcomments/:id(.:format)      repcomments#show
                              PUT    /articles/:article_id/comments/:comment_id/repcomments/:id(.:format)      repcomments#update
                              DELETE /articles/:article_id/comments/:comment_id/repcomments/:id(.:format)      repcomments#destroy

Here the models

class Repcomments < ActiveRecord::Base
  belongs_to :customer
  belongs_to :article
  attr_accessible :acknowledged, :body, :completed, :customer_id, :article_id
end

Here my controller repcomments

class RepcommentsController < ApplicationController
  # GET /repcomments
  # GET /repcomments.json
  def index
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomments = Repcomment.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @repcomments }
    end
  end

  # GET /repcomments/1
  # GET /repcomments/1.json
  def show
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomment = Repcomment.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @repcomment }
    end
  end

  # GET /repcomments/new
  # GET /repcomments/new.json
  def new
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomment = Repcomment.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @repcomment }
    end
  end

  # GET /repcomments/1/edit
  def edit
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomment = @comments.repcomments.find(params[:id])
  end

  # POST /repcomments
  # POST /repcomments.json
  def create
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomment = @comments.repcomments.build(params[:repcomment])

    respond_to do |format|
      if @repcomment.save
        format.html { redirect_to @repcomment, notice: 'Repcomment was successfully created.' }
        format.json { render json: @repcomment, status: :created, location: @repcomment }
      else
        format.html { render action: "new" }
        format.json { render json: @repcomment.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /repcomments/1
  # PUT /repcomments/1.json
  def update
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomment = @comment.repcomments.find(params[:id])

    respond_to do |format|
      if @repcomment.update_attributes(params[:repcomment])
        format.html { redirect_to @repcomment, notice: 'Repcomment was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @repcomment.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /repcomments/1
  # DELETE /repcomments/1.json
  def destroy
    @article = Article.find(params[:article_id])
    @comments = @articles.comments.find(params[:comment_id])
    @repcomment = @comments.repcomments.find(params[:id])
    @repcomment.destroy

    respond_to do |format|
      format.html { redirect_to repcomments_url }
      format.json { head :no_content }
    end
  end
end


NameError in Article#show
Showing /home/jean/rail/voix/app/views/articles/show.html.erb where line #70 raised:
undefined local variable or method `repcomments' for #<#<Class:0xaf24860>:0xaafe934>

So pretty much is the referencing

Upvotes: 1

Views: 1161

Answers (1)

Robin
Robin

Reputation: 21884

Just looking at your code, I can see one problem in your routes: :article and :picture need to be plural.

resources :articles do
    resources :pictures
    resources :comments do
        resources :repcomments
    end
end
resources :reports

Also, you don't need to nest :repcomments within :articles. In addition to what you already have in your routes, you can add:

resources :comments do
    resources :repcomments #and remove the other "resources :repcomments"
end

Yes, you would have resources :comments defined twice, but that's fine.

If you never do anything with comments outside the article scope, then you can write your routes like that:

resources :comments, only: [] do
    resources :repcomments
end

This way Rails wont generate the default rest routes (no /comments, no /comments/:id etc)

Upvotes: 4

Related Questions