I'm working on an app that allows users to comment on a single "work" (think blog post). The associations in the models are as follows:
class User < ActiveRecord::Base
has_many :works
has_many :comments
class Work < ActiveRecord::Base
belongs_to :user
has_many :comments
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
belongs_to :work
There's a form on the Works show page that allows users to post a comment:
<%= form_for(#comment) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Post a comment!" %>
</div>
<%= f.submit "Post", class: "btn btn-small btn-primary" %>
<% end %>
The Works controller is as follows. Note that I'm adding the build comment functionality here so that the form on the Works page functions:
class WorksController < ApplicationController
#before_filter :current_user, only: [:edit, :update]
def index
#works = Work.all
#comment = #work.comments.build(params[:comment])
#comment.user = current_user
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #works }
end
end
def create
#work = current_user.works.create(params[:work])
redirect_to current_user
end
def edit
#work = current_user.works.find(params[:id])
end
def new
#work = current_user.works.new
end
def destroy
#work = current_user.works.find(params[:id]).destroy
flash[:success] = "Work deleted"
redirect_to current_user
end
def update
#work = current_user.works.find(params[:id])
if #work.update_attributes(params[:work])
flash[:success] = "Profile updated"
redirect_to #work
else
render 'edit'
end
end
def show
#work = Work.find(params[:id])
#comment = #work.comments.build
#comment.user = current_user
#activities = PublicActivity::Activity.order("created_at DESC").where(trackable_type: "Work", trackable_id: #work).all
#comments = #work.comments.order("created_at DESC").where(work_id: #work ).all
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #work }
end
end
end
And lastly, here is the Comments controller:
class CommentsController < ApplicationController
before_filter :authenticate_user!
def index
#comments = Comment.all
end
def show
#comment = Comment.find(params[:id])
#activities = PublicActivity::Activity.order("created_at DESC").where(trackable_type: "Comment", trackable_id: #comment).all
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #comment }
end
def update
#comment = current_user.comments.find(params[:id])
if #comment.update_attributes(params[:comment])
flash[:success] = "Comment updated"
redirect_to #comment
end
end
def create
#work = Work.find(params[:id])
#comment = #work.comments.build(params[:comment])
#comment.user = current_user
if #comment.save
#flash[:success] = "Post created!"
redirect_to #work
else
render 'home#index'
end
end
end
end
When I attempt to submit a comment using the comment form on the works show view page, I get the following error:
Activerecord::RecordNotFound in CommentsController#create
Couldn't find Work without an ID
Why can't the application find the Work so that it can associate the comment to it?
EDIT 1:
Thanks to the answers below I edited the comment form:
<%= form_for(#work, #comment) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Post feedback or contribute content
to this work!" %>
</div>
<%= f.submit "Post", class: "btn btn-small btn-primary" %>
<% end %>
I'm still getting the same error after making the change to the form and adding the nested route.
I edited the routes file to include a nest for work comments:
authenticated :user do
root :to => 'activities#index'
end
root :to => "home#index"
devise_for :users
resources :users do
member do
get :following, :followers, :posts, :comments
end
end
resources :works do
resources :comments
end
resources :relationships, only: [:create, :destroy]
resources :posts
resources :activities
resources :comments
Rake routes shows the following for Comments#create:
POST /comments(.:format)
The POST URL (where the error shows up) is appURL/works/1/comments
Doesn't seem right. What do I need to change? Thank you so much for the help so far!!
Your form needs to be form_for([#work, #comment]) so that Rails knows to build a URL like /works/123/comments. Right now it would just be posting to /comments.
Check your rake routes to see the route for your CommentsController#create action. You might also need to tweak the controller to read params[:work_id] instead of params[:id].
The view helper form_for(#comment) will post to '/comments' by default. You can specify a url (see the guides) that includes the :id of the work record. The typical approach is to use form_for([#work, #comment]) and Rails will do this for you so long as you've set up your routes with comments as a nested resource of work.
Related
I am trying to make an app with Rails 4.
I use simple form for forms.
I am trying to follow this tutorial so that my polymorphic comments model can be used to add comments to articles. https://gorails.com/episodes/comments-with-polymorphic-associations?autoplay=1
I have models for article and comment as follows:
article.rb
has_many :comments, as: :commentable
accepts_nested_attributes_for :comments
comment.rb
belongs_to :user
belongs_to :commentable, :polymorphic => true
The comment controllers have been setup as shown in the video tutorial:
comments_controller.rb
Article/comments_controller.rb
The article controller has:
def new
#article = Article.new
#article.comments.build
end
def article_params
params[:article].permit(:user_id, :body, :title, :image, :tag_list,
comment_attributes: [:opinion])
end
The article show page has:
<div class="col-xs-12">
<%= render :partial => 'comments/form', locals: {commentable: #article} %>
</div>
The comments form partial has:
<%= simple_form_for [commentable, Comment.new] do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :opinion, as: :text, :label => "Add your thoughts", :input_html => {:rows => 4} %>
</div>
<div class="form-actions">
<%= f.button :submit, "Submit", :class => 'formsubmit' %>
</div>
<% end %>
The routes are:
resources :articles do
collection do
get 'search'
end
resources :comments, module: :articles
end
When I save all of this and try to render the articles show page, I get this error:
undefined method `new' for #
The error points to the comments controller create action:
def create
#comment = #commentable.new(comment_params)
#comment.user = current_user
respond_to do |format|
if #comment.save
format.html { redirect_to #commentable }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
I don't know what the problem is. I can't understand why this isn't working or what this error message means. I'm wondering if its because comment belongs to both user and commentable.
In fact when I push this and try to see it in production mode, I get a failure and heroku logs show this error:
Exiting
2016-01-02T02:27:59.274318+00:00 app[web.1]: /app/app/controllers/Articles/comments_controller.rb:1:in `<top (required)>': uninitialized constant Articles (NameError)
The entire Article/comments controller has:
class Articles::CommentsController < CommentsController
before_action :set_commentable#, only: [:show, :edit, :update, :destroy]
private
# Use callbacks to share common setup or constraints between actions.
def set_commentable
#commentable = Article.find(params[:article_id])
end
end
So this now works on new articles, but only for 1 comment. If I try and add a second comment to a single article, I get this error:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_comments_on_commentable_type_and_commentable_id" DETAIL: Key (commentable_type, commentable_id)=(Article, 4) already exists. : INSERT INTO "comments" ("opinion", "user_id", "commentable_id", "commentable_type", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
Try:
def create
#comment = Comment.new(comment_params)
#comment.user = current_user
#comment.commentable = #commentable
respond_to do |format|
if #comment.save
format.html { redirect_to #comment }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
Lots of issues.
This is how it should look:
--
#config/routes.rb
resources :articles do
get :search, on: :collection
resources :comments, module: :articles #-> url.com/articles/:article_id/comments
end
#app/controllers/articles/comments_controller.rb #-> this is the heroku error
class Articles::CommentsController < ApplicationController
before_action :set_article
respond_to :js, :json, :html
def create
#comment = #article.comments.new comment_params
respond_with #comment
end
private
# Use callbacks to share common setup or constraints between actions.
def set_article
#article = Article.find params[:article_id]
end
def comment_params
params.require(:comment).permit(:opinion).merge(user: current_user)
end
end
You should be creating comments as their own entity (not as a nested attribute of articles). You should do this using the following:
#app/views/articles/show.html.erb
<%= content_tag :div, render(partial: 'comments/form', locals: { article: #article }), class: "col-xs-12" %>
#app/views/comments/_form.html.erb
<%= simple_form_for [article, article.comments.new] do |f| %>
<%= f.input :opinion, as: :text, label: "Add your thoughts", input_html: {rows: 4} %>
<%= f.submit %>
<% end %>
This should create a standalone comment on the back of the Article that's been invoked.
I'm getting an error raised of "undefined method 'comments_path' for..."
At this code in app/views/comments/_form.html.erb (line 1).
I recently tried to implement nestable comments via polymorphic associations on a website I'm building; however, I'm running into a problem that's not allowing me to move forward.
I'm trying to implement nested comments on a 'commentable' model (ie the blog in this case) and then when show is clicked, all the nested comments are shown and the individual can comment on the blog or reply to a comment (and hence result in nested comments) without leaving the page.
I've included a few other files to show the setup, but if I've missed one that's necessary, please let me know and I'll promptly add it. Any help is much appreciated. I've been stumped for several hours and I'm sure its something simple.
<%= form_for [#commentable, #comment] do |f| %>
<%= f.hidden_field :parent_id %></br>
<%= f.label :content, "New Comment" %></br>
<%= f.text_area :body, :rows => 4 %></br>
<%= f.submit "Submit Comment" %>
<% end %>
app/views/blogs/show.html.erb
<div class="content">
<div class="large-9 columns" role="content">
<h2>Comments</h2>
<div id="comments">
<%= nested_comments #comments %>
<%= render "comments/form" %>
</div>
</div>
</div>
app/controllers/comments_controller
class CommentsController < ApplicationController
def new
#parent_id = params.delete(:parent_id)
#commentable = find_commentable
#comment = Comment.new( :parent_id => #parent_id,
:commentable_id => #commentable.id,
:commentable_type => #commentable.class.to_s)
end
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment])
if #comment.save
flash[:notice] = "Successfully created comment."
redirect_to #commentable
else
flash[:error] = "Error adding comment."
end
end
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def comment_params
params.require(:comment).permit(:parent_id, :body, :commentable_type, :commentable_id)
end
end
app/controller/blogs_controller.rb
class BlogsController < ApplicationController
before_filter :authenticate, :except => [ :index, :show ]
before_action :set_blog, only: [:show, :edit, :update, :destroy]
include MyModules::Commentable
# GET /blogs
# GET /blogs.json
def index
#blogs = Blog.all.order('created_at DESC')
respond_to do |format|
format.html
format.json
format.atom
end
end
# GET /blogs/1
# GET /blogs/1.json
def show
#blog = Blog.find(params[:id])
end
# GET /blogs/new
def new
#blog = Blog.new
end
# GET /blogs/1/edit
def edit
#blog = Blog.find(params[:id])
end
# POST /blogs
# POST /blogs.json
def create
#blog = Blog.new(blog_params)
respond_to do |format|
if #blog.save
flash[:success] = "Blog was sucessfuly created"
format.html { redirect_to #blog }
format.json { render :show, status: :created, location: #blog }
else
format.html { render :new }
format.json { render json: #blog.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /blogs/1
# PATCH/PUT /blogs/1.json
def update
respond_to do |format|
if #blog.update(blog_params)
flash[:success] = "Blog was successfully updated."
format.html { redirect_to #blog }
format.json { render :show, status: :ok, location: #blog }
else
format.html { render :edit }
format.json { render json: #blog.errors, status: :unprocessable_entity }
end
end
end
# DELETE /blogs/1
# DELETE /blogs/1.json
def destroy
#blog.destroy
respond_to do |format|
flash[:success] = "Blog was successfully deleted."
format.html { redirect_to blogs_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_blog
#blog = Blog.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def blog_params
params.require(:blog).permit(:title, :body, :image, :image_cache, :remote_image_url)
end
private
def authenticate
authenticate_or_request_with_http_basic do |name, password|
name == "admin" && password == "runfast"
end
end
end
my routes file looks like this...
Rails.application.routes.draw do
resources :blogs do
resources :comments
end
resources :applications
resources :reviews
resources :properties
root to: 'blogs#index'
end
the blog and comment models...
class Blog < ActiveRecord::Base
validates_presence_of :body, :title
has_many :comments, :as => :commentable, :dependent => :destroy
mount_uploader :image, ImageUploader
end
class Comment < ActiveRecord::Base
has_ancestry
belongs_to :commentable, :polymorphic => true
validates_presence_of :body
end
and finally the commentable module in lib/my_modules/commentable.rb
require 'active_support/concern'
module MyModules::Commentable
extend ActiveSupport::Concern
included do
before_filter :comments, :only => [:show]
end
def comments
#Commentable = find_commentable
#comments = #Commentable.comments.arrange(:order => :created_at)
#comment = Comment.new
end
private
def find_commentable
return params[:controller].singularize.classify.constantize.find(params[:id])
end
end
#blog
#<Blog id: 8, title: "New Blog Post about Databases.... Again", body: "RDM, the database management system, was designed ...", created_at: "2015-03-01 22:28:07", updated_at: "2015-03-03 00:11:07", image: "IMG_2210.JPG">
#commentable
#<Blog id: 8, title: "New Blog Post about Databases.... Again", body: "RDM, the database management system, was designed ...", created_at: "2015-03-01 22:28:07", updated_at: "2015-03-03 00:11:07", image: "IMG_2210.JPG">
app/helpers/comments_helper.rb
module CommentsHelper
def nested_comments(comments)
comments.map do |comment, sub_comments|
content_tag(:div, render(comment), :class => "media")
end.join.html_safe
end
end
#_params instance variable in better errors
{"utf8"=>"✓", "authenticity_token"=>"OH2tDdI5Kp54hf5J78wXHe//Zsu+0jyeXuG27v1REqjdAec7yBdlrVPLTZKEbLZxgR2L7rGwUwz5BlGTnPcLWg==", "comment"=>{"parent_id"=>"", "body"=>"Hello!\r\n"}, "commit"=>"Submit Comment", "controller"=>"comments", "action"=>"create", "blog_id"=>"8"}
You're getting the error in this view: app/views/blogs/show.html.erb.
The data for this view has been prepared in blogs#show. So in your view, you should have <%= form_for [#blog, #comment] do |f| %>, since you set #blog, not #commentable.
You should also do #comment = Comment.new. Not sure where you set this one...
Do <% raise #commentable.inspect %> in your view (app/views/blogs/show.html.erb). If it's nil, then that's why you're getting the error.
I'm trying to build a small expense tracking app using Rails 4.1. Using devise for authorization. Expense and it's nested attribute, comments belong to a user. The associations are set up in the model and expenses are getting associated with the user. Here's the Expense controller:
class ExpensesController < ApplicationController
def new
#expense = Expense.new
#item = #expense.items.build
##comment = #expense.comments.build
end
def index
#expenses = Expense.all
##items = Item.where(:expense_id => #expense.id)
end
def show
#expense = Expense.find(params[:id])
#items = Item.where(:expense_id => #expense.id)
end
def create
#expense = current_user.expenses.new(expense_params)
respond_to do |format|
if #expense.save
ExpenseMailer.expense_submission(#expense).deliver
format.html { redirect_to #expense, notice: 'Expense Report Submitted.' }
format.json { render :show, status: :created, location: #expense }
else
format.html { render :new }
format.json { render json: #expense.errors, status: :unprocessable_entity }
end
end
end
def edit
#expense = Expense.find(params[:id])
end
def update
#expense = Expense.find(params[:id])
##comment = #expense.comments.build
if #expense.update(expense_params)
#if #comment.save
#ExpenseMailer.comments_added(#expense).deliver
flash[:notice] = "Expense Report Updated"
redirect_to expenses_path
#else
# flash[:notice] = "Expense Report Updated"
#redirect_to expenses_path
##end
else
render 'edit'
end
end
The form from where the comment attributes are built looks like:
<%= nested_form_for (#expense) do |f| %>
<div class="form-group">
<%= f.label :state %><br />
<%= f.select :state, Expense.states, :include_blank => false, class: "form-control" %>
</div>
<%= f.fields_for :comments, #expense.comments.build do |comment| %>
<div class="form-group">
<%= comment.label :comment%>
<%= comment.text_area :comment, class: "form-control" %>
</div>
<%= comment.hidden_field :commenter %>
<% end %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
The #comment.commenter = current_user isn't adding the current user id to the database. Should I include it in the expense controller somewhere?
You have to add:
#comment.commenter = current_user
below that if statement. Like this:
def create
#article = Expense.find(params[:expense_id])
if #comment = #expense.comments.create(comment_params)
#comment.commenter = current_user
#comment.save
ExpenseMailer.comments_added(#expense).deliver
redirect_to expenses_path
end
end
And then save the comment again. In your current code you're overwriting the #comment object with the newly created object by doing:
#comment = #expense.comments.create(comment_params)
but you haven't set the commenter on that new object anywhere yet.
Model
I just tried to create better code for your strong params, but I couldn't work out how to include the param in your nested attributes
I would therefore recommend using the inverse_of: method in your Comment model to get it sorted properly:
#app/models/expense.rb
Class Expense < ActiveRecord::Base
belongs_to :user
has_many :comments, inverse_of: :expense
accepts_nested_attributes_for :comments
end
#app/models/comment.rb
Class Comment < ActiveRecord::Base
belongs_to :expense, inverse_of: :comments
before_create :populate_expense, on: :create
private
def populate_expense
self.commenter_id = self.expense.user_id
end
end
This should work if you're populating the comments from the accepts_nested_attributes_for directive
Comments
I don't understand why you've created two create actions for both your expenses and comments controllers - the controller action is meant to be independent of the Model
What I'm trying to say is that if you think the comments#create controller action will be invoked by your nested attribute creation, you'd be mistaken - it is only invoked when you send a request to it through the Rails router :)
If you're creating Comments and Expenses separately, you'll be able to use these two different actions; but they won't be invoked by each other. Only Model methods can be invoked by the controller (you shouldn't be calling other controller methods)
If you wanted to create a Comment from the expenses#show page, here's how you'd set it up:
#config/routes.rb
resources :expenses do
resources :comments #-> domain.com/expenses/:expense_id/comments/new
end
#app/controllers/expenses_controller.rb
Class CommentsController < ApplicationController
def new
#expense = Expense.find params[:expense_id]
#comment = #expense.comments.new
end
def create
#expense = Expense.find params[:expense_id]
#comment = #expense.comments.new(comment_params)
#comment.save
end
private
def comment_params
params.require(:comment).permit(:comment, :params).merge(commenter_id: current_user.id)
end
end
This will work if you wanted to create a comment from the expenses#show page. If you do this, you need to ensure you are calling the comments#new / comments#create actions, rather than those of the expenses controller
After successfully completeling a micropost system. Logged in users can post through the form and create a post. I begun to add to this but allowing any user to comment on a post as well.
I get a multitude of errors. And for the most part I don't know what the problem is so would like some advise on how to get this finished. Right now the error is:
NameError in StaticPages#home
undefined local variable or method `micropost'
StaticPages#home is the page that displays everyones microposts, and thus the comments form as well. users#show is the public profile of users and displays the same as statispages (have yet to work out how to make posts to a users wall, eventually main page will be a general feed and user page will be a user-to-user feed).
Comments model
create_table "comments", force: true do |t|
t.string "content"
t.integer "user_id"
t.integer "micropost_id"
t.datetime "created_at"
t.datetime "updated_at"
end
User.rb
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
has_many :comments
micropost.rb
belongs_to :user
has_many :comments, dependent: :destroy
comment.rb
belongs_to :user
belongs_to :micropost
comments_controller.rb
class CommentsController < ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
def create
#micropost = Micropost.find(params[:micropost_id])
#comment = Comment.new(params[:comment])
#comment.micropost = #micropost
#comment.user = current_user
if #comment.save
flash[:success] = "Comment created!"
redirect_to current_user
else
render 'shared/_comment_form'
end
end
end
microposts_controller.rb
class MicropostsController < ApplicationController
before_action :authenticate_user!
before_action :correct_user, only: :destroy
def index
#microposts = Micropost.all
#comment = #micropost.comments.build(params[:comment])
#comment.user = current_user
end
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
#feed_items = []
render root_url
end
end
def destroy
#micropost.destroy
redirect_to root_url
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
def correct_user
#micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if #micropost.nil?
end
end
users_controller.rb
def show
#user = User.find(params[:id])
#microposts = #user.microposts
#comment = Comment.new
if user_signed_in?
#micropost = current_user.microposts.build
#feed_items = current_user.feed
end
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #user }
end
end
Anyplace calling the comment form
<%= render 'shared/comment_form', micropost: micropost %>
_comment_form.html.erb
<%= form_for([micropost, #comment]) do |f| %> #Here's the current error#
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, :placeholder => "Leave a comment" %>
</div>
<button class="btn" type="submit">
Create
</button>
<% end %>
Schema shows all the correct fields of the model. All DB migrations have been done. I've seen it say that in form_for([micropost, #comment]) the first field cannot be nil. I'm assuming this means that the comments aren't correctly filling micropost_id with the id of the micropost they attach to.
So I'm trying to get the acts_as_commentable_with_threading gem working in my app. I would like to allow the users to comment on specific events (events/show.html). I don't think I've set it up properly as I'm getting the below error.
error:
Showing /Users/user/Sites/new_work/app/views/events/show.html.erb where line #36 raised:
First argument in form cannot contain nil or be empty
</div>
<div class="name"></div>
<div id="comments">
<%= form_for #comment do |f| %> <---- it's referring to this line
<div><%= f.hidden_field :event_id, value: #event.id %></div>
<div><%= f.text_field :body, row: 20, placeholder: "Leave a comment" %></div>
<%= f.submit "Post Comment" %>
comments_controller.rb
class CommentsController < ApplicationController
before_filter :load_commentable
def index
#comments = #commentable.current_user.comments
end
def new
#comment = #commentable.current_user.comments.new
end
def create
#comment = #commentable.current_user.comments.new(params[:comment])
if #comment.save
redirect_to #commentable, notice: "Comment created."
else
render :new
end
end
private
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
end
comment.rb snippit only
class Comment < ActiveRecord::Base
attr_accessible :title, :body, :subject
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
validates :body, :presence => true
validates :user, :presence => true
# NOTE: install the acts_as_votable plugin if you
# want user to vote on the quality of comments.
#acts_as_votable
belongs_to :commentable, :polymorphic => true
# NOTE: Comments belong to a user
belongs_to :user
event.rb
class Event < ActiveRecord::Base
attr_accessible :title, :description, :location, :date, :time, :event_date
acts_as_commentable
has_many :comments, as: :commentable
belongs_to :user
after_create :update_event_date
def update_event_date
date = self.date.to_s
time = self.time
hour = Time.parse(time).strftime("%H:%M:%S").to_s
event_date = (date + ' ' + hour).to_time
self.update_attributes(event_date: event_date)
end
end
comments/form.html.erb
<%= form_for [#commentable, #comment] do |f| %>
<% if #comment.errors.any? %>
<div class="error_messages">
<h3>Please correct the following errors.</h3>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_field :body, rows: 10, placeholder: "Leave a comment" %>
</div>
<div class="actions">
<%= f.submit "Post comment", class: "btn" %>
</div>
<% end %>
events_controller.rb
class EventsController < ApplicationController
before_filter :authenticate_user!
def index
#user = current_user
#events = Event.all
end
def new
#event = Event.new
end
# def create
# #event = Event.new(params[:event])
# if #event.save
# redirect_to :action => 'index'
# else
# #events = Event.find(:all)
# render :action => 'new'
# end
# end
def create
#event = current_user.events.new(event_params)
respond_to do |format|
if #event.save
format.html { redirect_to :back, notice: 'Event was successfully created.' }
format.json { render action: 'show', status: :created, location: #event }
format.js
else
format.html { render action: 'new' }
format.json { render json: #event.errors, status: :unprocessable_entity }
format.js
end
end
end
def show
#event = Event.find(params[:id])
end
def edit
#event = Event.find(params[:id])
end
def update
#event = Event.find(params[:id])
if #event.update_attributes(params[:event])
flash[:success] = "Event updated."
redirect_to #event
else
render 'edit'
end
end
def destroy
#event = Event.find(params[:id])
#event.destroy
respond_to do |format|
format.html {redirect_to :back}
format.js
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_event
#event = Event.find(params[:id])
end
routes.rb
New_app::Application.routes.draw do
# get 'auth/:provider/callback', to: 'sessions#create'
# get 'auth/failure', to: redirect('/')
root to: "home#landing"
devise_for :users, :controllers => {:registrations => "users/registrations",
:sessions => "users/sessions",
:passwords => "users/passwords",
:omniauth_callbacks => "users/omniauth_callbacks"
}
get "welcome", to: "home#welcome", as: 'welcome'
devise_scope :user do
# get "edit/edit_account", :to => "devise/registrations#edit_account", :as => "account_registration"
get 'edit/edit_account' => 'users/registrations#account_registration', as: :edit_account
end
# patch '/users/:id', to: 'users#update', as: 'user'
get 'profile/:id' => "users#show", as: :profile
get 'disconnect' => 'users#disconnect'
resources :users do
resources :questions
end
resources :photos
resources :events do
resources :comments
end
post "/events/add_new_comment" => "events#add_new_comment", :as => "add_new_comment_to_events", :via => [:event]
resources :questions
end
rake routes for comments
event_comments GET /events/:event_id/comments(.:format) comments#index
POST /events/:event_id/comments(.:format) comments#create
new_event_comment GET /events/:event_id/comments/new(.:format) comments#new
edit_event_comment GET /events/:event_id/comments/:id/edit(.:format) comments#edit
event_comment GET /events/:event_id/comments/:id(.:format) comments#show
PATCH /events/:event_id/comments/:id(.:format) comments#update
PUT /events/:event_id/comments/:id(.:format) comments#update
DELETE /events/:event_id/comments/:id(.:format) comments#destroy
Is #comment defined in the "show" action in your Events controller? Can you post the Events controller code as well?
One thing to double check is to ensure that the action that renders the view for show.html.erb has the #comment variable defined. You seem to be getting the message because the #comment variable in
<%= form_for #comment do |f| %>
Is currently nil when you render the view.
In the "show" action for the events controller, try setting the #comment variable by adding:
#comment = #event.comments.new
Edit 2: Make sure you've setup your routes.rb file to handle comments on events, so assuming youre using RESTful routes, something like this below in your routes.rb. If you could post the routes file that would be helpful too.
resources :events do
resources :comments
end
The error is on app/views/events/show.html.erb which means that your Events controller's show action is missing the #comment variable
def show
#event = Event.find(params[:id])
#comment = ....what ever you need to pull in the comments....
end