如何修复失效的JS ERB?实现Rails分类筛选AJAX刷新
Let's walk through fixing your AJAX functionality step by step—there are a couple of small issues in your current setup that are preventing the index.js.erb from working as expected.
1. Ensure Your Form Properly Triggers AJAX Requests
First, confirm you've added remote: true to your form. If you're on Rails 7+, you'll also want to disable Turbo for this form (since Turbo handles requests differently than traditional UJS):
<%= simple_form_for :search, url: root_path, method: "GET", remote: true, data: { turbo: false } do |f| %> <%= f.input :categories, label: "Category", collection: @all_tags, as: :check_boxes %> <%= f.submit "Search", class: "btn btn-primary" %> <%= link_to "Reset", root_path, remote: true, data: { turbo: false } %> <% end %>
Notice I also added remote: true and data-turbo="false" to the Reset link—this ensures it also triggers an AJAX request instead of a full page reload.
2. Fix the index.js.erb Logic
Your current index.js.erb has two key issues:
- You're passing incorrect locals to the partial (your
_categories.html.erbuses the@filterinstance variable, not acategorieslocal) - The way you check if
@filteris empty is error-prone (string comparison of[]can fail if the array is formatted differently)
Here's the corrected index.js.erb:
function replacePrograms(innerHTML) { const categoriesContainer = document.getElementById('categories'); categoriesContainer.innerHTML = innerHTML; } <% if @filter.empty? %> // When no filters are selected, render all categories replacePrograms("<%= j render 'home/categories' %>"); <% else %> // When filters are selected, render only the filtered categories replacePrograms("<%= j render 'home/categories' %>"); <% end %>
The j alias for escape_javascript ensures the rendered HTML is properly escaped for insertion into JavaScript. Since your _categories.html.erb iterates over @filter, we don't need to pass any locals—your controller already sets @filter correctly for both HTML and AJAX requests.
3. Verify Controller Setup
Your existing HomeController#index logic looks solid, but double-check that @filter is always set correctly for AJAX requests. When the form submits via AJAX, params["search"]["categories"] should still be available, so the existing conditional logic will populate @filter properly.
4. Ensure UJS is Loaded (For Rails 7+)
If you're using Rails 7, you'll need to make sure @rails/ujs is included in your JavaScript bundle. Add this to your app/javascript/application.js:
import "@rails/ujs" Rails.start()
This enables the Rails.fire method you're using in your checkbox change handler.
Testing the Fix
Once you've made these changes:
- Restart your Rails server to ensure all changes are loaded
- Click any category checkbox—your form should submit via AJAX, the controller will process the filter, and
index.js.erbwill replace the contents of the#categoriesdiv with the filtered results without a full page reload.
内容的提问来源于stack exchange,提问作者marcamillion

