1

I'm trying to create a comment on a video show page. When I submit the form, rails gives me a flash notice: "User must exist, Video must exist". Not sure why my strong params aren't going through to the create method.

comments_controller.rb

def create
    @user = current_user
    @video = Video.find(params[:video_id])
    @comment = Comment.new(comment_params)
    @post = @video.post

    if @comment.save
      flash[:notice] = "Comment successfully created"
      redirect_to post_video_path(@post, @video)
    else
      @errors = @comment.errors.full_messages.join(', ')
      flash[:notice] = @errors
      render :'videos/show'
    end

    private

    def comment_params
      params.require(:comment).permit(
        :body,
        :user,
        :video
      )
    end

models/comment.rb

    class Comment < ActiveRecord::Base
      belongs_to :user
      belongs_to :video

      validates :body, presence: true
    end

models/video.rb

    class Video < ActiveRecord::Base
      belongs_to :user
      belongs_to :post

      has_many :comments
    end

views/videos/show.html.erb

    <%= @video.title %>
    <%= content_tag(:iframe, nil, src: "//www.youtube.com/embed/#{@video.embed_id}") %>
    <%= link_to "Delete Video", post_video_path(@post, @video), method: :delete %>
    <%= link_to('Back', user_post_path(@user, @post)) %>

    <h3>Comments</h3>

    <%= form_for [@video, @comment] do |f| %>
      <%= f.label(:body, "Comment") %>
      <%= f.text_area(:body) %>
      <%= f.submit("Submit Comment") %>
    <% end %>

    <% unless @comments.nil? %>
      <% @comments.each do |comment| %>
        <%= comment.body %>
        <%= comment.user %>
      <% end %>
    <% end %>

I tried adding this to the create method...

@comment.user = current_user
@comment.video = @video

That allowed the comment to save but instead of displaying the comment.body, it displayed the comment object. It still doesn't explain why the strong params aren't being passed.

dnsh
  • 3,516
  • 2
  • 22
  • 47
n.milsht
  • 163
  • 3
  • 17

3 Answers3

0

This is probably a nested params issue and how you have the strong params defined. Check this answer for more information.

If you need to see what is in the params, insert a pry statement into the controller and inspect it there.

Good luck!

Community
  • 1
  • 1
engineerDave
  • 3,887
  • 26
  • 28
0

There are multiple things you should look at. I have made multiple changes to your code. Go through them.

In your videos/show.html.erb

<%= form_for Comment.new do |f| %>
  <%= f.label(:body, "Comment") %>
  <%= f.text_area(:body) %>
  <%= f.hidden_field :video_id, :value => @video.id %>
  <%= f.submit("Submit Comment") %>
<% end %>

Send video_id using hidden_field. Do not send current user id for security reasons. If you take current user id from form end user can easily edit your form in html and pass someone else's user id and this will be one of the easiest and major vulnerability.

In comments_controller.rb

def create
  @comment = Comment.new(comment_params)
  @comment.user = current_user # we are making sure that current_user is set to comment.
  if @comment.save
    flash[:notice] = "Comment successfully created"
    redirect_to post_video_path(@comment.video.post, @comment.video)
  else
    @errors = @comment.errors.full_messages.join(', ')
    flash[:notice] = @errors
    render :'videos/show'
  end
end

private

    def comment_params
      params.require(:comment).permit(:body, :user, :video_id)
      # We are permitting video_id instead of video
    end
dnsh
  • 3,516
  • 2
  • 22
  • 47
  • def create user = current_user video = Video.find(params[:video_id]) comment = Comment.new(comment_params) comment.user = user comment.video = video post = video.post def comment_params params.require(:comment).permit( :body, ) end – n.milsht Oct 18 '16 at 22:09
0

I got this to work but I'm not sure if this addresses the security concerns that @Dinesh raised.

comments_controller.rb

def create
  @user = current_user
  @video = Video.find(params[:video_id])
  @comment = Comment.new(comment_params)
  @comment.user = @user
  @comment.video = @video
  @post = @video.post
  if current_user == @video.user || current_user.admin
    if @comment.save
      flash[:notice] = "Comment successfully created"
      redirect_to post_video_path(@post, @video)
    else
      @errors = @comment.errors.full_messages.join(", ")
      flash[:notice] = @errors
      render :"videos/show"
    end
  else
    flash[:notice] = "Only OP or admin may comment"
    render :"videos/show"
  end
end

and

private

def comment_params
  params.require(:comment).permit(
    :body,
  )
end
Community
  • 1
  • 1
n.milsht
  • 163
  • 3
  • 17