Rails中jQuery-UI Autocomplete无返回结果求助
Let's break down the problems and fixes step by step:
1. Fix the Critical Model Method Bug
Looking at your Ingredient model code, there's a clear issue in the ingredient_name= method:
def ingredient_name=(name) self.ingredient = Ingredient.find_by_name(name) if name.present? end
Your Ingredient model only has a belongs_to :user association—there's no ingredient attribute or association defined here. Trying to assign self.ingredient will throw an error, which is almost certainly breaking the autocomplete flow.
What to do instead:
If you're using this method to let users select existing ingredients via a form (e.g., adding to a recipe), this logic belongs in the model that belongs to Ingredient (like a RecipeIngredient model), not the Ingredient model itself. For example:
# app/models/recipe_ingredient.rb class RecipeIngredient < ApplicationRecord belongs_to :recipe belongs_to :ingredient def ingredient_name ingredient&.name end def ingredient_name=(name) self.ingredient = Ingredient.find_by(name: name) if name.present? end end
If you want to create new ingredients automatically when a user types a new name, adjust the method to:
def ingredient_name=(name) self.ingredient = Ingredient.find_or_create_by(name: name, user: current_user) if name.present? end
(Note: Pass the current user if ingredients are user-specific.)
2. Set Up a Backend Endpoint for Autocomplete
Autocomplete needs a backend route to return matching ingredients as JSON. Add this to your routes.rb:
get '/ingredients/search', to: 'ingredients#search'
Then create a search action in your IngredientsController:
# app/controllers/ingredients_controller.rb def search @ingredients = Ingredient.where("name LIKE ?", "%#{params[:query]}%").where(user: current_user) render json: @ingredients.pluck(:name) end
This will return a list of ingredient names matching the user's input.
3. Add Frontend Autocomplete Logic
Assuming you're using jQuery UI Autocomplete (common in Rails apps), add this JavaScript (either in your asset pipeline or a Stimulus controller):
$(document).on('turbolinks:load', function() { $('#ingredient_name').autocomplete({ source: function(request, response) { $.get('/ingredients/search', { query: request.term }, function(data) { response(data); }); }, minLength: 1 // Start suggesting after 1 character is typed }); });
Make sure your HTML input has the correct ID to match the JS selector:
<div class="field"> <%= form.label :ingredient_name %> <%= form.text_field :ingredient_name, id: 'ingredient_name' %> </div>
4. Verify Validations and Permitted Params
- Double-check that your form's strong parameters include
ingredient_name(if using nested attributes). For example, in yourRecipeIngredientsController:def recipe_ingredient_params params.require(:recipe_ingredient).permit(:quantity, :ingredient_name) end - Confirm your
Ingredientmodel's name validation is scoped to the user if needed (to avoid duplicate names across users):validates :name, presence: true, uniqueness: { scope: :user }
Quick Debugging Checks
- Open your browser's developer tools (F12) and check the Console for JavaScript errors.
- Visit
/ingredients/search?query=your-ingredientdirectly in your browser to see if it returns the expected JSON list. - Ensure jQuery and jQuery UI are properly loaded in your application (if using that autocomplete library).
Let me know if you need help with any specific part of this!
内容的提问来源于stack exchange,提问作者Alex

