ruby on rails - relaciones - ¿Cómo enviar comentarios polimórficos sobre la alimentación?
relaciones laravel 5 (2)
Si un usuario hace clic en el botón [+ Comentario]
él se enfrenta a esta malvada bestia:
ActiveRecord::RecordNotFound in CommentsController#create
Couldn''t find Comment with ''id''=
Line: @commentable = resource.singularize.classify.constantize.find(id)
actividades / índice
<%= link_to activity.user.name, activity.user %>
<%= render "activities/#{activity.trackable_type.underscore}/#{activity.action}", activity: activity %>
<%= render "comments/comments", comments: activity.comments %>
<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name) %>
comentarios / _form
<%= form_for new_comment do |f| %>
<%= f.text_area :content, rows: 4, class: ''form-control'', placeholder: ''Enter Comment'' %>
<%= button_tag(type: ''submit'', class: "btn") do %>
<span class="glyphicon glyphicon-plus"></span> Comment
<% end %>
<% end %>
activities_controller
def index
@activities = Activity.order("created_at desc").where(user_id: current_user.following_ids)
@commentable = @activity
@comment = Comment.new
end
El error se puede encontrar aquí:
class CommentsController < ApplicationController
before_action :load_commentable
before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]
before_action :logged_in_user, only: [:create, :destroy]
def index
@comments = @commentable.comments
end
def new
@comment = @commentable.comments.new
end
def create
@comment = @commentable.comments.new(comment_params)
if @comment.save
redirect_to @commentable, notice: "comment created."
else
render :new
end
end
def edit
@comment = current_user.comments.find(params[:id])
end
def update
@comment = current_user.comments.find(params[:id])
if @comment.update_attributes(comment_params)
redirect_to @commentable, notice: "Comment was updated."
else
render :edit
end
end
def destroy
@comment = current_user.comments.find(params[:id])
@comment.destroy
redirect_to @commentable, notice: "comment destroyed."
end
def like
@comment = Comment.find(params[:id])
@comment_like = current_user.comment_likes.build(comment: @comment)
if @comment_like.save
@comment.increment!(:likes)
flash[:success] = ''Thanks for liking!''
else
flash[:error] = ''Two many likes''
end
redirect_to(:back)
end
private
def set_comment
@comment = Comment.find(params[:id])
end
def load_commentable
resource, id = request.path.split(''/'')[1, 2]
@commentable = resource.singularize.classify.constantize.find(id) #Here it is!
end
def comment_params
params[:comment][:user_id] = current_user.id
params.require(:comment).permit(:content, :commentable, :user_id, :like)
end
end
El error surgió de la respuesta aquí: ¿Cómo agregar comentarios polimórficos al feed?
desarrollo.log
Started POST "/comments" for ::1 at 2015-04-23 20:12:14 -0400
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hU1lxg2BMqSyBo8j2SGiEB4wZ3ez5kz/E64mp6ssbwBnh+DddyTtNQxY+IYCluHHvs2wIBxrtD5hQVA5sGtXBg==", "comment"=>{"content"=>"test"}, "button"=>""}
[1m[35mUser Load (0.2ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
[1m[36mHabit Load (0.1ms)[0m [1mSELECT "habits".* FROM "habits" WHERE "habits"."user_id" = ?[0m [["user_id", 2]]
[1m[35mHabit Load (2.5ms)[0m SELECT "habits".* FROM "habits"
[1m[36mActsAsTaggableOn::Tag Load (0.3ms)[0m [1mSELECT "tags".* FROM "tags" WHERE (LOWER(name) = LOWER(''ingrain''))[0m
[1m[35mComment Load (0.3ms)[0m SELECT "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT 1 [["id", nil]]
Completed 404 Not Found in 16ms
ActiveRecord::RecordNotFound (Couldn''t find Comment with ''id''=):
app/controllers/comments_controller.rb:61:in `load_commentable''
Muchas gracias!
El problema es que, para que esto funcione, parece que está configurado para que los comentarios sean un recurso anidado de lo que sea que estés comentando en tu archivo de rutas.
Entonces, si quiere comentarios sobre actividades, tendría:
resources :activites do
resources :comments
end
De esta forma, cuando el método #load_commentable distingue la ruta de la solicitud, obtendrá el commentable y el ID de los primeros dos segmentos.
En su lugar, parece que intentas usar los comentarios como un recurso de nivel superior.
ACTUALIZACIÓN: cuando llame a su parcial, simplemente pase el url helper que debe usar el formulario. Me gusta esto:
<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name), create_url: :activity_comments_path %>
Luego, en el parcial, simplemente invoque a ese helper y pase el resultado como la opción url, como esta:
<%= form_for new_comment, url: send(create_url, new_comment.commentable)
En el load_commentable
before action, puede redireccionar a una página de error o algo si @commentable
es nil
. Tal como está, está intentando acceder a los atributos de este objeto nil
en otros métodos ( create
en el caso de este error).