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

时间:2012-05-28 22:49:06

标签: ruby-on-rails-3 build resources nested associations

在我的应用中存在关联问题,我无法修复。 我的应用程序非常简单:有一个文章模型;每篇文章都有很多评论,每个评论都有很多票,在我的案例中是'upvotes' 为了解释我设计它的方式,我做了一个注释脚手架,编辑了注释模型和路由到嵌套资源,一切正常。现在,我基本上为'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 %>

为什么'upvotes'在这种情况下是未定义的,而在这里:

<%= 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

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

我的路线:

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

抱歉这么多代码。如果有人可能会回答这个问题,他们会非常棒! 提前谢谢!

3 个答案:

答案 0 :(得分:0)

  

为什么'upvotes'在这种情况下是未定义的,而在这里:

这是因为你在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

答案 1 :(得分:0)

您的错误消息,表示您尝试在upvotes上致电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

UpvotesController行动中,create也发生了奇怪的事情。

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

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

答案 2 :(得分:0)

一切都固定好了,现在工作正常。采用不同的方法并简单地使用Upvote.new而不是将其嵌套到注释和构建关联中,也编辑了我的路线。实施了马修福特的想法

  

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

感谢大家的帮助!