Rails has_many error - Couldn't find ID

2019-07-24 13:33发布

I have a Comment and Reply. comment has_many replies

routes.rb

resources :comments do
  resources :replies
end

When I open comments/index and then select comments/show I print information about all the replies that are related to that comment.

<% @comment.replies.each do |reply| %>

I can also create another reply. All this works properly.

The problem comes when I decide to edit one of those replies.

<%=  link_to 'Edit', edit_comment_reply_path(@comment.replies,reply) %>

The strange thing is that if there is a comment with an ID the same as the ID of the reply that I want to modify, the edit is working properly. It is not even necessary the particular reply that I want to modify to belongs to that comment. But in case I want to edit reply with ID for example 66, but there is not a comment with id 66, I get an error:

Couldn't find Comment with 'id'=65
<%=form_with(model: @reply, url: [Comment.find(params[:id]), @reply]) do |form| %>

This is replies/_form.html.erb which apparently works as an edit form as well. In this case the reply.id is 65 and it is looking for a comment with the same ID which is not present.

5条回答
放荡不羁爱自由
2楼-- · 2019-07-24 14:07

In your RepliesController change the set comment method to

 def set_comment
    @comment = Comment.find(reply_params[:comment_id])
  end
查看更多
放我归山
3楼-- · 2019-07-24 14:12

Ok, can you also post your comments controller. A few points: Make use of authorizations in your relevant functions (suggestion; assuming you're using policies)

def edit
  authorize @reply
end

If you plan on passing in the comment id, you should also set_comment (not just in create). That way you can also make sure the reply edit is not executed using a comment that does not belong to your user (or some other unwanted behaviours).

And also, you question talks about looking for Id 66, but the error mentions ID 65. Is that just a typo?

查看更多
劳资没心,怎么记你
4楼-- · 2019-07-24 14:20

The problem lies in this line of code.

<%= link_to 'Edit', edit_comment_reply_path(@comment.replies,reply) %>

The edit_comment_reply_path method takes @comment as its first argument.

The correct code should be

<%=  link_to 'Edit', edit_comment_reply_path(@comment, reply) %>

Provided that you have assigned @comment in your controller edit action.

def edit
    @comment = Comment.find(params[:comment_id])
end

Or

before_action :set_comment, only: [:create, :edit]

The point is you must set the @comment in the correct action for the view.

The form_for is incorrect. You can passing in params[:id] which is the id of @reply.

<%= form_with(model: @reply, url: comment_reply_path(@comment, @reply)) do |form| %>
查看更多
不美不萌又怎样
5楼-- · 2019-07-24 14:24

What do your controllers look like? Also, you shouldn't be able to access replies that do not belong to your comment. Look at using proper scoping and authorization. I would guess the only reason it works is luck; because you do have a comment_id that matches the reply_id, the call does not fail.

查看更多
Summer. ? 凉城
6楼-- · 2019-07-24 14:28

Did you try?

<%=  link_to 'Edit', edit_comment_reply_path(reply) %>
查看更多
登录 后发表回答