How to Submit Polymorphic Comments on Feed? [Error]

How to Submit Polymorphic Comments on Feed? [Error]

The problem is, for this to work, it looks like it is setup for comments to be a nested resource of whatever you're commenting on in your routes file.

So, if you want comments on activities, you'd have:

resources :activites do
resources :comments
end

This way, when the #load_commentable method picks apart the request path, it'll get the commentable and id from the first two segments.

It looks, instead, like you're trying to use comments as a top level resource.

UPDATE:
When you call your partial, simply pass along the url helper that the form should use. Like this:

<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name), create_url: :activity_comments_path %>

Then, over in the partial, simply invoke that helper and pass the result as the url option - like this:

<%= form_for new_comment, url: send(create_url, new_comment.commentable)

Polymorphic comments route error

@Katie, @commentable should be loaded for every action on which you are rendering the comment form. I think you are forgoing comments#new in favor of using books#show or posts#show to render the form (which is fine), but that variable needs to be loaded every time you want to render the form.

However, since defining a @commentable variable in books#show isn't very expressive (you probably already have a @book defined), here's what I would suggest:

Create a new partial (if you don't have one already) for the comment form:

<% form_for [commentable, Comment.new] do |f| %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>

Notice commentable is not an instance variable here. When you render the partial, you will define it as a local variable. Somewhere in books/show.html.erb:

 <%= render partial: "comments/form", locals: { commentable: @book } %>

Obviously, in other views, replace @book with whatever variable should be commentable.

Now you'll have another issue, which is that the form data won't carry the commentable_type and commentable_id attributes. There are a number of ways you can get them into your CommentsController; here's a simple one using hidden fields:

<% form_for [commentable, Comment.new] do |f| %>
<%= hidden_field_tag :commentable_type, commentable.class.to_s %>
<%= hidden_field_tag :commentable_id, commentable.id %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>

You'll need to change the find_commentable action to something a bit more simple:

def find_commentable
params[:commentable_type].constantize.find(params[:commentable_id])
end

Polymorphic Association with Comments - Ruby on Rails

Your issue is that find_commentable is returning the params hash itself because the return statement never fired.

I deduced this by the error message because params.class == ActiveSupport::HashWithIndiffrentAccess

def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
end

I would add something like

def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
raise ActiveRecord:NoRecord.new("Couldn\'t find it captain!")
end

The above exception type I think is correct, if not see what Comment.find_by_id(-1) or something like that raises. Should be something along those lines.

Edit

The reason I suggest raising the exception is because ApplicationController should be catching those and handling them gracefully when people start poling around and go to example.com/posts/9001

Rails polymorphic comments ajax - 500 (Internal Server Error)

updated create.js with instance variable for comment and it works now.

<% unless @comment.errors.any? %>
$("ul.comments").append('<%= j render partial: "comments/comment", locals:{comment: @comment} %>')
$("#new_comment")[0].reset();
<% end %>

rails-3, new comment form from a polymorphic association, accepts form submission but doesn't display submited data

If you look at app/views/comments/_form.html.erb you'll notice that it
builds a form using

[@post, Comment.new]

This means that it works correctly when you create a comment directly from a PostsController
view as @post is set correctly. This means that the form
builder sets the form's action to /posts/5/comments (where the 5 is
taken from @post.id), thus setting the post_id param which the CommentsController
looks for in CommentsController#get_parent.

However, when you click on 'Add a comment' or 'Add a reply' you are in
the CommentsController, which sets a variable called @parent. That
means that the form builder sets the form's action to /comments
(since @post is nil), which means when you submit the form both the post_id and
comment_id params are nil.

What this means that it reaches this line in CommentsController#get_parent:


redirect_to root_path unless defined?(@parent)

which means that your form contents are silently discarded.

The easiest way to get the forms to work correctly is to make the
following changes:


#app/controllers/posts_controller.rb:

def show
- @post = Post.find(params[:id])
+ @parent = @post = Post.find(params[:id])
end

#app/views/comments/_form.html.erb b/app/views/comments/_form.html.erb

-
+

As you'll see, it means that the form looks for the @parent object
(instead of @post), which then gets set by PostsController & CommentsController.

As an aside, you could consider making the following changes to tighten up your code:


- redirect_to root_path unless defined?(@parent)
+ redirect_to root_path unless @parent

If @parent is not defined it will return nil, which is considered false.


- return @post if defined?(@post)
- @post = commentable.is_a?(Post) ? commentable : commentable.post
+ @post ||= commentable.is_a?(Post) ? commentable : commentable.post

Also, you call Comment.new in your views. Generally, initializing object should be done in a controller, and views should be limited to presentation logic.

Rails polymorphic comments associate

Relationships:

class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
belongs_to :user
end

class Photo < ActiveRecord::Base
has_many :comments, as: :commentable, dependent: :destroy
end

class User < ActiveRecord::Base
has_many :comments, dependent: :destroy
has_many :messages, as: :commentable, class_name: 'Comment'
end

Schema:

# Comments
...
t.integer :user_id
t.integer :commentable_id
t.string :commentable_type
...

Then you can invoke:

@user.comments # Get all comments created by particular user
@user.messages # Get all comments where particular user is a subject

Rails - embedded polymorphic comment list + add comment form - example?

I figured it out, implemented it, tested it, then finally wrote a tutorial explaining how to do it for others:

https://github.com/hcatlin/make_resourceful/wiki/embedded-nested-polymorphic-comments



Related Topics



Leave a reply



Submit