Reputation: 1754
I have item
s, that each have multiple (threaded) comment
s.
The threading is done via a parent
key, that points towards another comment
.
I just can't get the create
action to work properly, I got it far enough to submit into the database, but it didn't have item_id
and parent_id
set.
I tried form_for [@item, @comment]
instead of form_for :comment, url: item_comments_path( @item )
but it didn't help either.
When I look at comment_params
in the create
action I get this:
Parameters: {"utf8"=>"✓", "comment"=>{"body"=>"examplecommentgoeshere"}, "parent_id"=>"4", "commit"=>"Create Comment", "item_id"=>"4"}
Can anyone help?
class Item < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
has_many :images, as: :item,
dependent: :destroy
validates :title, presence: true,
allow_blank: false
validates :description, presence: true,
allow_blank: false
validates :user, presence: true,
allow_blank: false
validates :layout, presence: true
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :item
has_many :responses, class_name: "Comment",
foreign_key: "parent_id",
dependent: :destroy
has_one :image, as: :item,
dependent: :destroy
belongs_to :parent, class_name: "Comment"
validates :body, presence: true,
allow_blank: false,
length: { minimum: 10 }
end
class CommentsController < ApplicationController
before_filter :findParent
before_filter :find, only: [:update, :destroy, :show]
before_filter :is_logged_in?, only: [:create, :update, :destroy]
before_filter :has_permission?, only: [:update, :destroy]
def new
@comment = Comment.new
end
def create
logger.debug comment_params.inspect
@comment = current_user.comments.build(comment_params)
if @comment.save
redirect_to @item
else
logger.debug @comment.errors.inspect
session[:errorbj] = @comment
redirect_to @item
end
end
[...]
private
def comment_params
params.require(:comment).permit(:body, :parent)
end
private
def find
@comment = Comment.find(params[:id])
end
private
def findParent
@item = Item.find params[:item_id]
end
<p>
<h3>Add a comment:</h3>
<%= render partial: 'comments/form', locals: { parent: @item } %>
</p>
<%= form_for :comment, url: item_comments_path( @item ) do |f| %>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.label :image %><br>
<nope>
</p>
<%= hidden_field_tag :parent_id, parent.id %>
<p>
<%= f.submit %>
</p>
<% end %>
From another stackoverflow thread I concluded that the only way to create an object in a multi-association is to do something along the lines of this:
@comment = current_user.comments.build( comment_params.join( { parent_id: <parent.id> } ) )
Other stackoverflow posts however said not to do
@item = Item.new( item_params.join( { user_id: current_user.id } )
So is there really no better way?
Upvotes: 0
Views: 2524
Reputation: 1754
It turns out this is much easier than it seemed.
This is how I ended up doing it:
class CommentsController < ApplicationController
before_filter :findParent, only: [:create]
[...]
def create
@comment = current_user.comments.build(comment_params)
@comment.item = @item
if @comment.save
redirect_to @item
else
session[:errorbj] = @comment
redirect_to @item
end
end
Upvotes: 0
Reputation: 18845
i think there are a lot of errors in your code. i hope that i can put that into a form that might help you figure out the fix by yourself:
form_for [@item, @comment]
findParent
should be find_parent
findParent
should set a @parent
findParent
should find a Comment
new
action should initialize with a parent @comment = Comment.new parent: @parent
hidden_field_tag :parent_id, parent.id
should be form.hidden_field :parent
comment_params
Rails.logger
statement, its all in logs/development.logitem
and image
?learn more about debugging! http://nofail.de/2013/10/debugging-rails-applications-in-development/
Upvotes: 1