2015-09-19 16 views
-3

我正试图在嵌套到拍卖中的评论中实现嵌套的答案。嵌套的评论与嵌套的答案:未定义的方法`答案为零:NilClass | Rails

有一个auctions.rb模型,其中:

has_many :comments, dependent: :destroy 
has_many :answers, :through => :comments 

一个comments.rb模型,其中:

belongs_to :auction 
has_many :answers, dependent: :destroy 

一个answers.rb模型,其中:

belongs_to :comment 

answers_controller继承自comments_controller:

class AnswersController < CommentsController 
    before_action :all_answers, only: [:index, :create, :update, :destroy] 
    before_action :set_answer, only: [:edit, :update, :destroy] 
    respond_to :html, :js 

    # New Answer (Form) 
    def new 
    @answer = Answer.new 
    @comments.answers.build 
    end 

    # Create Answer 
    def create 
    @answer = @comment.answers.build(answer_params) 
    @answer.user_id = current_user.id 
    @answer.save 
    end 

    # Edit Answer 
    def update 
    @answer.update!(answer_params) 
    end 

    # Delete Answer 
    def destroy 
    @answer = Comment.find(params[:id]) 
    @comment = @answer.comment 
    @answer.destroy 
    end 

    private 

    def all_answers 
    @answers = @comment.answers.all 
    end 

    def set_answer 
    @answer = @comment.answers.find(params[:id]) 
    end 

    def answer_params 
    params.require(:comment).permit(:body) 
    end 
end 

的错误:

NoMethodError in Auctions#show app/views/comments/_comment.html.erb where line #20 raised: undefined method `answers' for nil:NilClass

 <div class="col s12" id="answer-form" style="display:none;"></div> 
    </div> 
    <div class="row"> 
    <div class="col s12" id="answers"><%= render @comment.answers %></div> 
    </div> 

随着<%=渲染@ comment.answers%>我要显示的相关注释下所有现有的答案。我究竟做错了什么?

auction_controller

class AuctionsController < ApplicationController 
    # Index of all auctions 
    def index 
    @auctions = Auction.all 
    end 

    # Show Auction by :id 
    def show 
    @auction = Auction.find(params[:id]) 
    # Find Seller by ID 
    @seller = User.find(@auction.user_id) 
    # Find highest bid, by finding all related bids and ordering in descending and picking the first 
    @highest_bid = Bid.where(auction_id: params[:id]).order("amount DESC").first 
    # Find product 
    @product = Product.find(@auction.product_id) 
    end 

    # New Auction Form 
    def new 
    @auction = Auction.new 
    end 

    # Edit Auction 
    def edit 
    @auction = Auction.find(params[:id]) 
    end 

    # Create new Auction 
    def create 
    # Create new Auction 
    @auction = Auction.new(auction_params) 
    # Save Id of User (Seller) 
    @auction.user_id = current_user.id 
    # If auction was created successfully 
    if @auction.save 
     # display the created auction 
     redirect_to @auction, :notice => "Auction created" 
    else 
     # display Form again if unsuccessful 
     render 'new' 
    end 
    end 

    # Update existing Auction 
    def update 
    @auction = Auction.find(params[:id]) 
    # Validation 
    if @auction.update(auction_params) 
     redirect_to @auction, :notice => "Auction updated" 
    else 
     render 'edit' 
    end 
    end 

    # Delete Auction 
    def destroy 
    @auction = Auction.find(params[:id]) 
    @auction.destroy 

    redirect_to auctions_path, :notice => "Auction deleted" 
    end 

    private 
    # set required parameters for new created Auctions 
    def auction_params 
    params.require(:auction).permit(:condition, :product_name) 
    end 
end 

comments_controller

class CommentsController < ApplicationController 
    before_action :set_auction 
    before_action :all_comments, only: [:index, :create, :update, :destroy] 
    before_action :set_comment, only: [:edit, :update, :destroy] 
    respond_to :html, :js 

    # New Comment (Form) 
    def new 
    @comment = Comment.new 
    @auction.comments.build 
    end 

    # Create Comment 
    def create 
    @comment = @auction.comments.build(comment_params) 
    @comment.user_id = current_user.id 
    @comment.save 
    end 

    # Edit Comment 
    def update 
    @comment.update!(comment_params) 
    end 

    # Delete Comment 
    def destroy 
    @comment = Comment.find(params[:id]) 
    @auction = @comment.auction 
    @comment.destroy 
    end 

    private 
    def set_auction 
    @auction = Auction.find(params[:auction_id]) 
    end 

    def all_comments 
    @comments = @auction.comments.all 
    end 

    def set_comment 
    @comment = @auction.comments.find(params[:id]) 
    end 

    def comment_params 
    params.require(:comment).permit(:body) 
    end 
end 

正常工作的意见。只有评论回答不起作用。

+0

错误提出的动作是什么?新?指数?等等? –

+0

的行为是:Auctions#show,我们可以看到您的拍卖控制器吗?看起来@comment没有定义。 –

+0

@SimoneCarletti - 错误在拍卖的展示行为中引发。 –

回答

0

该错误发生在Auctions#show,该错误清楚地告诉您,您试图在无对象上调用answers。因此,这意味着@comment在该视图中为零。

实际上,如果您检查show操作,则永远不会将任何对象读取/分配给@comment

# Show Auction by :id 
    def show 
    @auction = Auction.find(params[:id]) 
    # Find Seller by ID 
    @seller = User.find(@auction.user_id) 
    # Find highest bid, by finding all related bids and ordering in descending and picking the first 
    @highest_bid = Bid.where(auction_id: params[:id]).order("amount DESC").first 
    # Find product 
    @product = Product.find(@auction.product_id) 
    end 

为了解决这个问题,确保@comment正确地分配给Comment实例。

0

这里有一个问题:

def new 
    @answer = Answer.new 
    @comments.answers.build 
    end 

你有没有一个叫@comments变量,因此您的形式不能真正建立答案关闭它。事实上,你调用两个@comment其他方法,在这里我甚至无法看到它正在宣布:

def all_answers 
    @answers = @comment.answers.all 
    end 

    def set_answer 
    @answer = @comment.answers.find(params[:id]) 
    end 

你声明@comment是在destroy方法的唯一时间:

def destroy 
    @answer = Comment.find(params[:id]) 
    @comment = @answer.comment 
    @answer.destroy 
    end 

即使这样,它很奇怪。

你为什么要用@answer变量调用Comment模型?当然你会有一个Answer模型与comments作为has_many关系的方式附加?

我建议你保持它的死脑筋简单:

#app/models/answer.rb 
class Answer < ActiveRecord::Base 
    has_many :comments 
end 

#app/models/comment.rb 
class Comment < ActiveRecord::Base 
    belongs_to :answer 
end 

这意味着,当你打电话给你的动作控制器,你就可以申请以下:

def show 
    @answer = Answer.find params[:id] 
    @comment = @answer.comments.build 
end 

如果你想让评论充当答案,你需要保持模型独立。使用hierchy宝石,如closure tree。这样,您就可以按照层次结构顺序保留您的答案/评论,同时保持模型的一致性。

+0

感谢您的回答。我不得不提,我在2周前开始学习rails。首先,我只有拍卖和评论模式。正常的评论工作正常(评论就像一个问题btw)。然后,我想,只需在评论中实现答案就很容易(就像我在拍卖中实施评论一样)。因此,我做了这样的路线:'资源:拍卖做 资源:评论做 资源:答案 结束 结束' 是我想要做的解决方案完全不可能? –

+0

不错!你有任何以前的编程经验?在开始学习的2周内尝试看起来相当复杂! –

+1

我只知道html,css,一点js,java和cake/php。到现在为止,我更关注前端。但是,由于我意识到如果我可以做后端开发,我会立即开始学习Ruby基础知识和Rails。是的,它对我来说非常复杂,但我认为学习某些东西的最好方法就是通过这样做并从失败中学习。 –

相关问题