Rails 3 - 在另一个嵌套资源中构建嵌套资源(文章 -> 评论 -> 投票)



在我的应用程序中存在关联问题,我无法修复。我的应用程序非常简单:有一个文章模型;每篇文章has_many评论,每条评论has_many投票,在我的例子中是"赞成票"。
为了解释我设计它的方式,我做了一个注释脚手架,编辑了注释模型和嵌套资源的路由,一切正常。现在,我基本上再次对"upvotes"执行了相同的过程,并再次编辑了模型和路由,使其成为注释嵌套资源中的嵌套资源。但这在以下一点上失败:

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

我的 _form.html.erb 文件如下所示:

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

为什么在这种情况下没有定义"赞成票",而在这里:

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

一切正常?我复制了相同的机制,但使用 @comment.upvotes 它不起作用。

我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

我很抱歉这么多代码..,我articles_controller:(摘录)

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

还有我的 3 个模型:

  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

对迁移文件投赞成票:

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

我的路线:

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

对不起,代码太多了。如果有人能回答这个问题,他们会非常棒!提前谢谢你!

为什么在这种情况下没有定义"赞成票",而在这里:

这是因为您正在对 nil 对象调用 upvotes,该注释尚不存在。

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

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

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

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

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

  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])

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

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

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

感谢大家的帮助!

最新更新