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!