【问题标题】:Rails: Adding a post without refreshing the pageRails:添加帖子而不刷新页面
【发布时间】:2021-11-18 08:18:39
【问题描述】:

我是 ruby​​ on rails 的新手。

我目前正在开发一个 facebook 克隆应用程序,在不刷新页面的情况下添加帖子时遇到问题。尝试创建帖子,但帖子在提交时未显示并遇到内部服务器错误。当页面刷新时,新创建的帖子终于显示出来了。

rails 服务器出错

Completed 500 Internal Server Error in 50ms (ActiveRecord: 15.9ms | Allocations: 10085)



ActionView::Template::Error (First argument in form cannot contain nil or be empty):
    1: = form_for([post, @comment]) do |f|
    2:   .form-bottom-button-container
    3:     .d-flex.comment-text-button
    4:       .p-2.flex-grow-1

这是我的代码。请帮帮我。非常感谢!

app/controllers/posts_controller.rb

def create
  @post = current_user.posts.build(post_params)
  respond_to do |format|
    if @post.save
      format.js
      format.html { redirect_to posts_path, notice: 'Successfully posted.'}
    else
      format.html { redirect_to posts_path, status: :unprocessable_entity }
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end
end

app/views/posts/create.js.haml

:plain
  $("#post-display").append("#{escape_javascript(render 'post_display', post: @post)}");

app/views/posts/index.html.haml

-# All Posts
.col-8
  .post-form
    = render "post_form"
  - if @posts.empty?
    .post-card
      .post-text
        .no-post-text No posts to show
  - else
    #post-display
      = render partial: "post_display", collection: @posts, as: :post

app/views/posts/_post_display.html.haml

.post-card
  .post-text
    .d-flex.justify-content-between
      .d-flex
        .post-user-image
          - if post.user.profile_pic.present?
            = image_tag post.user.profile_pic.url, class: "img img-fluid img-thumb"
          - else
            = image_tag "/default-user.jpg", class: "img img-fluid img-thumb"
        .d-flex.flex-column
          .username-bold= link_to post.user.username, profile_path(post.user.username)
          .distance-date= distance_of_time_posted_in_words(post.created_at)
      .post-edit-delete
        - if post.user.username == current_user.username
          = link_to edit_post_path(post), class: "text-space", remote: true, "data-bs-toggle" => "modal", "data-bs-target" => "#edit-post-#{post.id}-modal" do
            %i.fa.fa-edit
          .modal.fade(id="edit-post-#{post.id}-modal" tabindex="-1" aria-labelledby="edit-post-title" aria-hidden="true")
            .modal-dialog.modal-dialog-centered.modal-dialog-scrollable
              .modal-content
          = link_to post, method: :delete, class: "text-space" do
            %i.fa.fa-trash
    .caption= post.caption
  - if post.image.present?
    = image_tag post.image.url, class: "img img-fluid img-fill"

  -# Like Button
  .row.container-margin-top
    .col-6
      - if liker(post)
        = button_to post_like_path(post, liker(post)), method: :delete, class: "btn btn-maroon btn-wide btn-like-comment" do
          %i.far.fa-thumbs-up
          Unlike
      - else
        = button_to post_likes_path(post), method: :post, class: "btn btn-plain btn-wide btn-like-comment" do
          %i.far.fa-thumbs-up
          Like
    .col-6
      .btn.btn-plain.btn-wide.btn-like-comment.btn-comment
        %i.far.fa-comment
        %span Comment

  -# Comment Section
  .comment-box
    .d-flex.justify-content-between
      - unless post.likes.count == 0
        .post-likes(type="button" data-bs-toggle="modal" data-bs-target="#likers-#{post.id}-modal")= "#{pluralize(post.likes.count, "like")}"
        = render "layouts/likers_modal", post: post, index: post.id
      .comment-toggle View Comments
    .comment-display.hidden
      = render "posts/comments", post: post
  .comment-form
    = render "comments/comment_form", post: post

app/views/cmets/_comment_form.html.haml

= form_for([post, @comment]) do |f|
  .form-bottom-button-container
    .d-flex.comment-text-button
      .p-2.flex-grow-1
        = f.text_area :content, class: "comment-text-area comment", placeholder: "Write a comment..."
      .p-2
        = f.submit :Comment, class: "btn btn-maroon create-comment-button"

【问题讨论】:

    标签: ruby-on-rails ruby haml


    【解决方案1】:

    检查您的应用程序日志 - 它可能会告诉您 format.js 方法不存在。

    def create
      @post = current_user.posts.build(post_params)
      respond_to do |format|
        if @post.save
          format.js # <----
          format.html { redirect_to posts_path, notice: 'Successfully posted.'}
        else
          format.html { redirect_to posts_path, status: :unprocessable_entity }
          format.json { render json: @post.errors, status: :unprocessable_entity }
        end
      end
    end
    

    只需删除该行或使用format.json 方法即可。

    【讨论】:

    • 我之前用过format.json方法,效果很好,但问题是创建帖子时,页面会刷新以显示新帖子。我希望我的页面在不刷新页面的情况下显示新帖子。除了我做的,还有其他方法吗?
    【解决方案2】:

    要使页面不刷新,您必须使用 ajax 请求提交表单...您只需将 remote: true 添加到表单。

    form_for([post, @comment], remote: true) do |f|
    

    你得到的错误也是因为没有设置@comment。

    【讨论】:

    • 我明白了。当我在控制器中设置 @comment 时,错误现在消失了。但是,即使我将remote: true 放入表单,新帖子也不会显示。
    • 您在发布后是否在日志中看到任何错误?
    • 我在我的 Rails 服务器中看不到任何错误。还检查了控制台日志,但没有错误。
    • Rendered posts/_comments.html.haml (Duration: 9.0ms | Allocations: 1679) Rendered comments/_comment_form.html.haml (Duration: 0.8ms | Allocations: 231) Rendered posts/_post_display.html.haml (Duration: 53.8ms | Allocations: 21307) Rendered posts/create.js.haml (Duration: 69.3ms | Allocations: 23944) Completed 200 OK in 116ms (Views: 78.0ms | ActiveRecord: 15.3ms | Allocations: 30128)
    • 您是否在浏览器中检查过控制台日志?也许这是一个javascript错误,你安装了jquery吗?
    猜你喜欢
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多