form_with产生第一个记录为nil

时间:2018-12-24 04:01:28

标签: ruby-on-rails ruby ruby-on-rails-5

评论控制器

  public static String getPhoneNumber() // returns the phone number formatted as a sequence of digits
    {

        String regex = "^\\(?([0-9]{3})\\)?[-.\\s]?([0-9]{3})[-.\\s]?([0-9]{4})(?:Tel:)$";
        Pattern pattern = Pattern.compile(regex);
        for (int i = 0; i < line.length(); i++) 
        {
              //if phone number format includes -, . , spaces, + sign in front
              if (line.matches("[+]?\\d?[- .]?(\\([0-9]\\d{2}\\)|[0-9]\\d{2})[- .]?\\d{3}[- .]?\\d{4}$")) {
                phoneNumber = line.replaceAll("[^\\d.]", "").replace("-", "").replace(".", "").replace(" ", "").replace("(", "").replace(")", "")
                        .replace("+", "");

              }
              else
              {
                  getEmailAddress();
              }
                  }
        //System.out.println(phoneNumber);
        return phoneNumber;
    }

我创建评论的表单:

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

我看到的结果是enter image description here

如果需要更多信息,请问我,以便我提供

注意:我不确定此空记录是由于commentable.comments为零还是我错过了某件事

我在显示页面上评论了渲染表单,现在空记录消失了,所以我的问题必须与form_with

有关

enter image description here

1 个答案:

答案 0 :(得分:2)

据我了解,你

期望:

  • 在您的articles#show页面中不显示空白的by _________ <div> HTML,因为comment仍是内置的(仍在内存中),尚未保存(不是尚未在DB中使用。)

解决方案1:

app / views / articles / 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: https://stackoverflow.com/questions/1253426/what-is-the-difference-between-build-and-new-on-rails/1253462
    
    # 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)
    

这就是为什么在您的页面中,由于您正在呼叫而在页面中显示“内置”注释的原因

<%= render partial: 'comments/form', :locals => {commentable: @article} %> ...呼叫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>应该已经不显示了。