Reputation: 745
In my app that I am building to learn RoR, I have a similar situation like this question. Now my question is how to change my views for this?
I have an Annotation model, a Document model and a Comment model. If I switch to a polymorphic association such that my Annotations and my Documents can have Comments, how to do the view (in the partial)?
This is the current partial:
<%= simple_form_for([@annotation, @annotation.comments.build], html: { class: 'form-vertical', multipart: true }) do |f| %>
<%= f.error_notification %>
<%= f.input :commenter, :as => :hidden, :input_html => { :value => current_user.username }, label: false %>
<%= f.input :body, placeholder: 'comment', focus: true, label: false %>
<%= f.button :submit, 'Save' %>
<% end -%>
Did further research and have changed as follows in my annotation view: <%= render 'comments/form', :object => @annotation%>
and as follows in my documents view: <%= render 'comments/form, :object => @document %>
And adjusted this in my partial:
<%= simple_form_for([object, object.comments.build], html: { class: 'form-vertical', multipart: true }) do |f| %>
Now, when adding a comment to a document, I get an error in my CommentsController - logical that is :-) .
ActiveRecord::RecordNotFound in CommentsController#create
This is my current CommentsController:
class CommentsController < ApplicationController
def create
@annotation = Annotation.find(params[:annotation_id])
@comment = @annotation.comments.create(comment_params)
redirect_to annotation_path(@annotation)
end
def destroy
@annotation = Annotation.find(params[:annotation_id])
@comment = @annotation.comments.find(params[:id])
@comment.destroy
redirect_to annotation_path(@annotation)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
How (best) to change this ?
I now have implemented the same for another object/model/class called "tag" using :as => :tagable
and I can create, list, etc for the Annotation, yet I cannot delete.
The listing (as a partial) is called with:
<%= render 'tags/tag_list', :object => @annotation %>
or:
<%= render 'tags/tag_list', :object => @document %>
When opening the Annotation / Document record, it throws the error:
undefined method `object' for # Did you mean? object_id
... on this line:
<td><%= link_to '', [tag.object, tag], method: :delete, data: { confirm: 'Please confirm deletion!' }, :class => "glyphicon glyphicon-remove" %></td>
What should I change ??
change line to
<td><%= link_to '', [object, tag], method: :delete, data: { confirm: 'Please confirm deletion!' }, :class => "glyphicon glyphicon-remove" %></td>
Upvotes: 0
Views: 158
Reputation: 230346
You have to fetch correct commentable somehow. The simplest solution would be like this:
def create
commentable = detect_commentable
commentable.comments.create(comment_params)
redirect_to commentable_path(commentable)
end
private
def commentable_path(commentable)
case commentable
when Document
document_path(commentable)
when Annotation
annotation_path(commentable)
else
fail 'unknown commentable'
end
end
def detect_commentable
if params[:annotation_id]
Annotation.find(params[:annotation_id])
elsif params[:document_id]
Document.find(params[:document_id])
else
fail 'Commentable not found'
end
end
It is not the best code, obviously (because of maintenance requirements, for one thing). But this should get you started.
Upvotes: 1