Reputation: 115
I'm building a forum app where users can create posts and comment them, at this point the post functionally works fine but the comment form only works once and from then on the post page crashes showing the following error:
NoMethodError in Post#show
undefined method `to_key' for # Did you mean? to_set to_ary
through rails console i can see that the comment was saved.
here is the terminal error:
ActionView::Template::Error (undefined method `to_key' for #<Comment::ActiveRecord_Relation:0x007fb845e9cca8>
Did you mean? to_set
to_ary):
7: <h3>Reply to thread</h3>
8:
9: <div class="comments_form">
10: <%= form_for @comment, url: new_comments_path(@post), method: :post, remote: true do |f| %>
11: <%= f.label :title %><br>
12: <%= f.text_field :title, placeholder: "Type the comment title here" %><br>
13: <%= f.label :content %><br>
app/views/post/show.html.erb:10:in `_app_views_post_show_html_erb__4054771198415677123_70214711817160'
here is the form:
<%= form_for @comment, url: new_comments_path(@post), method: :post, remote: true do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title, placeholder: "Type the comment title here" %><br>
<%= f.label :content %><br>
<%= f.text_area :content, placeholder: "Type the comment content here" %><br>
<%= f.submit %>
<% end %>
rails mention that error is in this line of the form:
<%= form_for @comment, url: new_comments_path(@post), method: :post, remote: true do |f| %>
the comment_controller.rb:
class CommentController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def index
@comments = Comment.all
end
def new
@comment = Comment.new
end
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment].permit(:comment))
@comment.user = current_user
@comment.assign_attributes(comment_params)
if @comment.save
format.html { redirect_to @link, notice: 'Comment was successfully created.' }
format.json { render json: @comment, status: :created, location: @comment }
else
format.html { render action: "new" }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
def destroy
@comment.destroy
respond_to do |format|
format.html { redirect_to :back, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_comment
@comment = Comment.find(params[:id])
end
def comment_params
params.require(:comment).permit(:post_id, :content, :title, :user_id)
end
end
the routes.rb:
devise_for :users
root to: 'post#index'
#Posts
get '/posts/new', to: 'post#new'
get '/post/:id', to: 'post#show', as: 'show'
get '/post/:id/edit', to: 'post#edit', as: 'edit'
post '/post', to: 'post#create'
put '/post/:id', to: 'post#update', as: 'update'
delete '/post/:id', to: 'post#destroy', as: 'delete'
#Comments
post '/post/:post_id', to: 'comment#create', as: 'new_comments'
and the post_controller:
class PostController < ApplicationController
def index
if params[:user].blank?
@posts = Post.all.order("created_at DESC")
else
posts = Post.where(user_id: @user_id).order("created_at DESC")
end
end
before_action :authenticate_user!
before_action :find_post, only: [:show, :edit, :update, :destroy]
def show
if Comment.where(post_id: @post.id).present?
@comment = Comment.where(post_id: @post.id)
else
@comment = Comment.new
end
end
def new
@post = Post.new
end
def create
@post = Post.new
@post.user_id = current_user.id.to_i
#Post.create(title: title.string, content: content.string, user_id: current_user.id)
@post.assign_attributes(post_params)
if @post.save
flash[:notice] = "Successfully created post!"
#Post.create(title: title.string, content: content.string, user_id: current_user.id)
redirect_to show_path(@post)
else
flash[:alert] = "Error creating new post!"
render :new
end
end
def edit
end
def update
@post.assign_attributes(post_params)
if @post.changed?
@post.save
redirect_to show_path(@post)
else
render edit_path(@post)
end
end
def destroy
@post.destroy
redirect_to root_path#, notice: “Post destroyed”
end
private
def post_params
params.require(:post).permit(:title, :content, :user_id)
end
def find_post
@post = Post.find(params[:id])
end
end
Thanks in advance for your help.
Upvotes: 0
Views: 57
Reputation: 1837
I think replacing this line:
<%= form_for @comment, url: new_comments_path(@post), method: :post, remote: true do |f| %>
with this:
<%= form_for @post.comments.new, url: new_comments_path(@post), method: :post, remote: true do |f| %>
Should fix the issue!
Upvotes: 1