Rails 6 Bootstrap 5 Ajax 调用加载所有 user_notes 而不仅仅是 current_user 的注释

问题描述 投票:0回答:1

我有一个名为 user_notes 的连接表,它将 Adventure_id 与 user_id (belongs_to)连接起来,并有一个长文本字段 :note。问题是,在加载页面以及成功的 ajax 调用后,每个用户都可以看到其他用户的注释(每个用户的注释应该是私有的)。 JS 似乎忽略了控制器中的任何正确查询,甚至 JS 中的条件也不起作用。所有 ajax 和模式/表单更新都运行良好。但是,任何仅显示当前用户的注释的传统尝试(例如,使用嵌入的 ruby <% if %> 包装注释部分)都会破坏 ajax 功能。

user_notes_controller.rb

  def index
    @adventure = Adventure.find(params[:adventure_id])
    @user = current_user
    @user_notes = current_user.user_notes.where(adventure: @adventure).order(created_at: :desc)
  end

index.html.erb

<div class="container">


  <!-- New Note Form -->
  <div class="row mt-4 card">
    <div class="col-12">
      <h3 class="text-center">Add a New Note</h3>
      <h6 class="text-center">(SHIFT + RETURN/ENTER for a new line)</h6>

      <%= form_with(model: [@adventure, UserNote.new], url: adventure_user_notes_path(@adventure), local: false, method: :post, id: 'note_form') do |form| %>
        <%= form.text_area :note, oninput: 'this.style.height = "";this.style.height = this.scrollHeight + "px"', class: "form-control", placeholder: 'Add a new note...' %>
        <%= form.hidden_field :adventure_id, value: @adventure.id %>
        <%= form.hidden_field :user_id, value: @user.id %>
    </div>
      <div class="d-inline-flex justify-content-center">
        <%= form.submit 'Save Note', class: "btn btn-outline-success text-end" %>
      </div>
  </div>

      <% end %>


      <!-- Display Saved Notes -->
      <div class="container-fluid overflow-auto">
        <div id="user-notes-list">
          <%= render partial: 'user_notes/note', collection: @adventure.user_notes.order(created_at: :desc), as: :note, locals: { adventure_id: @adventure.id, user_id: @user.id } %>
        </div>
      </div>
      <div class="modal fade" id="editNoteModal" tabindex="-1" aria-labelledby="editNoteModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="editNoteModalLabel">Editing Note</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body" id="editNoteModalContent">
              <!-- Content from _edit_form.html.erb will be loaded here -->
            </div>
          </div>
        </div>
      </div>

</div><!-- End Container -->


<script><!-- Modal for Edit Note Form -->
// Update the list of notes in the DOM after successful Ajax response
$(document).on('ajax:success', '#note_form', function (event, data, status, xhr) {
    $('#editNoteModal').modal('hide'); // Hide the modal

    // Check if the note belongs to the current user
    if (data.user_id === $('body').data('current-user-id')) {
        $('#user-notes-list').html(data); // Update the list of notes
    }
});

$(document).on('click', '.edit-note-btn', function () {
    const noteId = $(this).data('note-id');
    const adventureId = $(this).data('adventure-id');

    $.ajax({
        url: `/adventures/${adventureId}/user_notes/${noteId}/edit_form`,
        method: 'GET',
        dataType: 'html',
        success: function (formHtml) {
            $('#editNoteModalContent').html(formHtml); // Load the form HTML into modal content
            $('#editNoteModal').modal('show'); // Show the modal
        }
    });
});

</script>

_note.html.erb(部分)

<div class="user-note mt-2" id="note_<%= note.id %>">
  <div class="text-dark card d-block p-2"><%= simple_format(note.note) %>
  <!-- Edit and Delete buttons -->
    <button class="btn btn-outline-primary edit-note-btn" data-bs-toggle="modal" data-bs-target="#editNoteModal" data-note-id="<%= note.id %>" data-adventure-id="<%= adventure_id %>">Edit</button>
    <%= link_to 'Delete', adventure_user_note_path(adventure_id: note.adventure, id: note), method: :delete, remote: true, class: 'delete-note btn btn-outline-danger content-justify-center', data: { confirm: 'Are you sure?' } %>
  <!-- end Edit and Delete buttons -->
  </div>
</div>

我已经为此工作了大约 9 个小时。我在 application.html.erb 的 body 标签中包含了

data-current-user-id="<%= current_user.id %>"
,这样 JS 就可以通过 JS 脚本中的条件 IF 语句来传递该内容;没有什么区别。

我尝试用

<% if note.user_id == @user.id %>
包装 _note.html.erb 代码,然后继续显示...那有效!...但是,它破坏了 ajax 流动性并强制重新加载页面以查看更新的更改。尝试了各种方法在控制器中定义@user_notes;没什么要紧的。我尝试了许多其他修复(甚至 OpenAI 推荐的一些修复),但都无济于事。

javascript ajax ruby-on-rails-6 bootstrap5-modal
1个回答
0
投票

已修复。有类似问题的人的答案:

在我们渲染部分的index.html.erb中

<%= render partial: 'user_notes/note', collection: @user_notes, as: :note %>

摆脱所有当地的东西。在 _note 部分中,将 data-adventure-id 的值更改为

<%= note.adventure_id %>
。然后确保
@user_notes = current_user.user_notes.where(adventure: @adventure).order(created_at: :desc)
出现在控制器的每个操作中(索引、创建、更新、销毁)。我尝试通过将其定义为 before_action 来清理控制器中的代码,但它再次破坏了它(不会显示过去的用户注释),所以我没有遵循 DRY 约定,并将其放回去,所以现在它可以工作了漂亮。希望这可以帮助其他尝试将 AJAX/JS 与连接表集成的人。

© www.soinside.com 2019 - 2024. All rights reserved.