1
votes

I have typical article and comment blog format. It's a typical has_many/belongs_to, ie, the Guide's blog type.

However, I'm trying to edit the comment within the article, and I'm clueless about building the right form for this.

It's also in a partial which makes it more complicated for me.

Any help and/or educating me would be appreciated.

Comment's model

class Comment < ApplicationRecord
  belongs_to :article
end

Article's model

class Article < ApplicationRecord

    has_many :comments

    validates :title, presence: true, length: { minimum: 5} 

end

Article's Show page

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<h2>Comments</h2>
<%= render @article.comments %>

<h2>Add a comment:</h2>
<%= render 'comments/form' %>

<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>

Comment's _comment.html.erb page

<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>

<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>


<p>
  <%= link_to 'Destroy Comment', [comment.article, comment],
               method: :delete,
               data: { confirm: 'Are you sure?' } %>
</p>

<p>
    <%= link_to 'Edit', edit_article_comment_path(@article, comment) %>
</p>

Comment's _form.html

<%= form_for([@article, @comment]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

Error

It comes from Comment's _form.html.erb page in reference to this line: <%= form_for([@article, @comment]) do |f| %> ... and the error is: First argument in form cannot contain nil or be empty ...

Articles Controller

class ArticlesController < ApplicationController


    def index
        @articles = Article.all 
    end


    def new
        @article = Article.new
    end

    def edit 
        @article = Article.find(params[:id])
    end

    def create
        #render plain: params[:article].inspect
        #@article = Article.new(params[:article])
        #@article = Article.new(params.require(:article).permit(:title, :text))
        @article = Article.new(article_params)

        if @article.save 
            redirect_to @article 
        else
            render 'new'
        end
    end

    def update 
        @article = Article.find(params[:id])

        if @article.update(article_params)
            redirect_to @article 
        else
            render 'edit'
        end
    end


    def show 
        @article = Article.find(params[:id])
    end

    def destroy 
        @article = Article.find(params[:id]) 
        @article.destroy 

        redirect_to articles_path 
    end


    private 
        def article_params
            params.require(:article).permit(:title, :text)
        end

end

Comments Controller

class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to article_path(@article)
  end

  def destroy 
    @article = Article.find(params[:article_id])
    @comment = @article.comments.find(params[:id])
    @comment.destroy 
    redirect_to article_path(@article) 
  end

  private
    def comment_params
      params.require(:comment).permit(:commenter, :body)
    end
end
1
Please post controller action where you set @article and @comment.Gerry
Also, how are rendering that partial?Pavan
show your comment controllerlakhvir kumar
@Gerry, mea culpa for such a late response. Have posted both Articles and Comments controller.user273072545345
@Pavan, not sure what you mean by how I'm rendering the partial ... thought it was visible in Article's show page? I.e., <%= render @article.comments %> and <%= render 'comments/form' %> ... sorry for late response.user273072545345

1 Answers

2
votes

First argument in form cannot contain nil or be empty

The error is due to @article and @comment being nil in the form. Since you are rendering the form with a partial, you need send variables to the partial as well

Change <%= render 'comments/form' %> to <%= render 'comments/form', article: @article, comment: @comment %>

and in the form have this <%= form_for([article, comment]) do |f| %>

Also in the show method of articles controller, you should define @comment

def show 
  @article = Article.find(params[:id])
  @comment = Comment.new
end