Рельсы: Добавление поста без обновления страницы

#ruby-on-rails #ruby #haml

Вопрос:

Я новичок в 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
 

Вот мои коды. Пожалуйста, помогите мне. Большое спасибо!

приложение/контроллеры/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
 

приложение/просмотры/сообщения/create.js.haml

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

приложение/просмотры/сообщения/индекс.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
 

приложение/просмотры/сообщения/_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
 

приложение/просмотры/комментарии/_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"
 

Ответ №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 метод, и все готово.

Комментарии:

1. Я использовал format.json этот метод раньше, и он хорошо работал, но проблема в том, что при создании поста страница обновляется для отображения нового поста. Я хочу, чтобы на моей странице отображалась новая запись без обновления страницы. Есть ли другой способ, кроме того, который я сделал?

Ответ №2:

Чтобы страница не обновлялась, вы должны отправить форму с помощью ajax-запроса… вы просто добавляете remote: true в форму.

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

Также ошибка, которую вы получаете, заключается в том, что @comment не задан.

Комментарии:

1. Я понимаю. Ошибки теперь исчезли, когда я установил @comment свой контроллер. Но все равно новая запись не отображается, даже когда я помещаю remote: true ее в форму.

2. Видите ли вы какие-либо ошибки в журналах после публикации?

3. Я не вижу никаких ошибок на своем сервере rails. Также проверил журнал консоли, но в нем нет ошибок.

4. 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)

5. Вы проверили журналы консоли в своем браузере? может быть, это ошибка javascript, у вас установлен jquery?