form_with производит первую запись как ноль - PullRequest
0 голосов
/ 24 декабря 2018

контроллер комментариев

class CommentsController < ApplicationController
  before_action :load_commentable
  before_action :checked_logged_in, only: [ :create]

  def new
    @comment = @commentabl.comments.new
  end

  def create
    @comment = @commentable.comments.new(comment_params) 
    @comment.user_id = current_user.id
    @comment.commenter = current_user.username


    if @comment.blank? || @comment.save
      flash[:success] = "Commented was created"
       ActionCable.server.broadcast 'comment_channel',
        commenter: current_user.username,
        comment: @comment.content
      redirect_to @commentable
    else       
       flash[:danger]  = render_to_string(:partial => 'shared/error_form_messaging',
                                          :locals => {obj: @comment}, 
                                          format: :html)
       redirect_to @commentable   
    end
  end
private

  def comment_params
      params.require(:comment).permit(:content, :commenter, :user_id)
  end
  def load_commentable
    resource, id = request.path.split('/')[1,2]
    @commentable = resource.singularize.classify.constantize.find(id)
  end

  def checked_logged_in
    unless logged_in?
      flash[:danger] = 'please log in to be able to comment'
      redirect_to login_path
    end
  end

end

моя форма для создания комментария:

<%= form_with  model:[commentable, commentable.comments.new], :html => {class: "form-horizontal", role:"form"} , local: true do |form| %>

<div class="form-group">
    <div class="control-label col-sm-2">
         <%= form.label :content, 'Comment' %>
    </div>
    <div class="col-sm-8">
         <%= form.text_field :content , class: 'form-control', placeholder: "enter your comment here", autofocus: true %>
    </div>
</div>
<div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
        <%= form.submit 'Comment' , class: ' btn btn-primary' %> 
    </div>
</div>              
<% end %>   

форма вызывается в show.html.erb

<h2 class="text-center">
    Title: <%= @article.title %>
</h2>
<div class="well col-xs-8 col-xs-offset-2">
    <div id="user-info-showpage" align="center">
        Created by: <%= render 'shared/user-info', obj: @article.user %>    
    </div>    
    <h4 class="text-center">
        <strong>Description:</strong>         
    </h4>
    <hr />
    <%= simple_format(@article.description) %>
    <% if @article.categories.any? %>
        <p>Categories: <%= render @article.categories %></p>      
     <% end %>
        <div class="article-actions">  
            <% if logged_in? && (current_user == @article.user || current_user.admin?) %>
                 <%= link_to "Delete", article_path(@article), method: :delete, 
                 data: {confirm: "Are you sure you want to delete the article?"}, 
                 class: 'btn btn-xs btn-danger' %>
                 <%= link_to "Edit", edit_article_path(@article), class: 'btn btn-xs btn-success'%>
            <%end%> 
            <%= link_to "View All Articles", articles_path  , class: 'btn btn-xs btn-primary'%> 
        </div> 
</div> 
<% if logged_in? %>
    <div class="col-xs-8 col-xs-offset-2">
        <%#= render partial: 'comments/form', :locals => {commentable:   @article} %>   
    </div>
<%end%> 

<div class="col-xs-8 col-xs-offset-2"> 
     <div id="comments"></div>
     <%= @article.comments.inspect %>
        <% @article.comments.each do |c| %>     
            <div class="well">           
                    <%= c.content %>   by 
                    <%= c.commenter %>           
            </div>
        <%end%>

     <div id="comments"></div>
</div>

мой результатна виду enter image description here

Пожалуйста, если вам нужна дополнительная информация, попросите меня предоставить

Примечание: Я не уверен, что эта пустая запись причитаетсяна commentable.comments будет ноль, или я что-то пропустил

Я прокомментировал форму рендеринга на странице шоу, и теперь пустая запись исчезла, поэтому моя проблема должна быть связана с form_with

enter image description here

1 Ответ

0 голосов
/ 24 декабря 2018

Насколько я понимаю, вы

ожидаете:

  • на вашей странице articles#show, чтобы не показывать пустой by _________ <div> HTML, потому что comment по-прежнемувстроенный (все еще в памяти) и еще не сохраненный (еще не в БД).

Решение 1:

app / views / article / show.html.erb

...
<div class="col-xs-8 col-xs-offset-2"> 
  <div id="comments"></div>
    <% @article.comments.each do |c| %>
      <!-- ADD THIS LINE -->
      <% if c.persisted? %>
        <div class="well">           
          <%= c.content %>   by 
          <%= c.commenter %>           
        </div>
      <% end %>
    <%end%>
  <div id="comments"></div>
</div>
...

Решение 2 (лучше, но это обходной путь):

app / views / comments / _form.html.erb

<%= form_with  model:[commentable, Comment.new(commentable: commentable)], :html => {class: "form-horizontal", role:"form"} , local: true do |form| %>

Объяснение:

  • Причина, по которой на странице отображается пустой by _________ <div>, заключается в том, что вы "построили" новый comment до .eachназывается.Поскольку они совместно используют одно и то же пространство памяти, build в основном также добавляет его в массив в памяти.См. Следующее:

    # rails console
    article = Article.create!
    comment1 = Comment.create!(commentable: article)
    # from here, comment1 is then saved already in the DB
    
    # now let's see what happens when you use "build" or "new"
    # They have differences, it seem: for details: /1314885/v-chem-raznitsa-mezhdu-sborkoi-i-novoi-na-rails
    
    # redefine (to simulate your @article = Article.find(params[:id])
    article = Article.find(article.id)
    comment2 = article.comments.build
    
    puts article.comments.count
    # SQL: Select count(*) FROM ...
    # => 1
    
    puts article.comments.size
    # => 2
    
    # notice how `count` and `size` are different. `count` value is "DB-based" while `size` is "memory-based". This is because `count` is an `ActiveRecord` method while `size` is a delegated `Array` method.
    
    # now let's simulate your actual problem in the view, where you were looping...
    article.comments.each do |comment|
      puts comment
    end
    # => <Comment id: 1>
    # => <Comment id: nil>
    
    # notice that you got 2 comments:
    #  one is that which is already persisted in DB
    #  and the other is the "built" one
    
    # the behaviour above is to be expected because `.each` is a delegated `Array` method 
    # which is agnostic to where its items come from (DB or not)
    

По этой причине на вашей странице отображается "встроенный" комментарий, поскольку вы звоните

* 1043.* ... который вызывает commentable.comments.build

ДО <% "article.comments.each do |c| %>

Если это еще не ясно, попробуйте ввести

<%= render partial: 'comments/form', :locals => {commentable: @article} %>

... который вызывает commentable.comments.build

ПОСЛЕ <% "article.comments.each do |c| %> ... <% end %> ... и by _________ <div> уже не должны отображаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...