我有一个名为 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 推荐的一些修复),但都无济于事。
已修复。有类似问题的人的答案:
在我们渲染部分的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 与连接表集成的人。