1

In my app there is an association problem, which I'm unable to fix. My app is quite simple: There's an Article model; each article has_many comments, and each of those comments has_many votes, in my case 'upvotes'.
To explain the way I designed it, I did a comments scaffold, edited the comment models and routes to a nested resource, everything works fine. Now, I basically did the same process again for 'upvotes' and again edited model and routes to make this a nested resource within the comment nested resource. But this fails at the following point:

NoMethodError in Articles#show
Showing .../app/views/upvotes/_form.html.erb where line #1 raised:
undefined method `upvotes' for nil:NilClass

My _form.html.erb file looks like this:

<%= form_for([@comment, @comment.upvotes.build]) do |f| %>
<%= f.hidden_field "comment_id", :value => :comment_id %>
<%= image_submit_tag "buttons/upvote.png" %>
<% end %>

Why is 'upvotes' undefined in this case, whereas here:

<%= form_for([@article, @article.comments.build]) do |form| %>
rest of code

everything works totally fine? I copied the same mechanism but with @comment.upvotes it doesn't work.

My upvotes_controller:

class UpvotesController < ApplicationController

  def new
    @upvote = Upvote.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @upvote }
    end    
  end

  def create
  @article = Article.find(params[:id])
  @comment = @article.comments.find(params[:id])
    @upvote = @comment.upvotes.build(params[:upvote])
    respond_to do |format|
      if @upvote.save
        format.html { redirect_to(@article, :notice => 'Voted successfully.') }
        format.xml  { render :xml => @article, :status => :created, :location => @article }
      else
        format.html { redirect_to(@article, :notice => 
        'Vote failed.')}
            format.xml  { render :xml => @upvote.errors, :status => :unprocessable_entity }
      end
    end
  end

end

I'm sorry for this much code.., my articles_controller: (extract)

def show
    @upvote = Upvote.new(params[:vote])
    @article = Article.find(params[:id])
    @comments = @article.comments.paginate(page: params[:page])


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

And my 3 models:

  class Article < ActiveRecord::Base
    attr_accessible :body, :title

    has_many :comments
  end

  class Comment < ActiveRecord::Base
    attr_accessible :content

    belongs_to :user
    belongs_to :article
    has_many :upvotes
  end

  class Upvote < ActiveRecord::Base
    attr_accessible :article_id, :comment_id, :user_id

    belongs_to :comment, counter_cache: true
  end

Upvote migration file:

  class CreateUpvotes < ActiveRecord::Migration
    def change
      create_table :upvotes do |t|
        t.integer :comment_id
        t.integer :user_id

        t.timestamps
      end
    end
  end

My routes:

  resources :articles do
      resources :comments, only: [:create, :destroy] do
        resources :upvotes, only: [:new, :create]
      end
    end

Sorry for that much code. If anyone might answer this, they would be so incredibly awesome! Thank you in advance!

4

3 回答 3

0

您的错误消息说您尝试 call upvoteson nil。具体来说,它是@comment.upvotes.build/app/views/upvotes/_form.html.erb视图中代码的一部分。

您必须通过添加(带有内容)变量来修复show您的操作。ArticlesController@comment

  def show
    @upvote = Upvote.new(params[:vote])
    @article = Article.find(params[:id])
    @comments = @article.comments.paginate(page: params[:page])


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

UpvotesControllercreate行动中也发生了奇怪的事情。

@article = Article.find(params[:id])
@comment = @article.comments.find(params[:id])
@upvote = @comment.upvotes.build(params[:upvote])

首先,您@article使用获取了一个params[:id],然后您获取了该@article(通过关联)的所有评论,其中评论 id 与@articleid 相同。请检查您的代码,它不一致并且无法正常工作。

于 2012-05-28T23:18:21.727 回答
0

现在一切都已修复并且工作正常。采取了不同的方法,简单地使用 Upvote.new 而不是将其嵌套到评论和建立关联中,也编辑了我的路线。实现了马修福特的想法

我怀疑你在文章页面上有很多评论,评论变量应该是本地的,例如@article.comments.each do |comment| 然后使用评论变量来构建您的投票表格。

谢谢大家的帮助!

于 2012-05-30T14:21:22.713 回答
0

为什么在这种情况下“upvotes”未定义,而在这里:

这是因为您正在对 nil 对象进行投票,但该评论尚不存在。

最好的办法是查看嵌套属性:

http://guides.rubyonrails.org/2_3_release_notes.html#nested-attributes

http://guides.rubyonrails.org/2_3_release_notes.html#nested-object-forms

于 2012-05-28T23:11:15.643 回答