2016-12-24 1 views
-2

Bonjour Je n'arrive pas à comprendre la cause de l'erreur lors de la recherche du Sphinx. Controller:NoMethodError, méthode non définie

class SearchesController < ApplicationController 
def show 
    @results = Search.get_results(params[:query], params[:context]) 
end 
end 

Modèle:

class Search < ApplicationRecord 
    CONTEXTS = ['Questions', 'Answers', 'Comments', 'Users'] 

    def get_results(query, context) 
    query = ThinkingSphinx::Query.escape(query) 
    klasses = [context.singularize.constantize] if CONTEXTS.include?(context) 
    @results = ThinkingSphinx.search(query, classes: klasses, order: 'model_order ASC') if query.present? 
    end 
end 

Erreur: NoMethodError dans SearchesController # show,

undefined method `get_results' for Search(id: integer, created_at: datetime, updated_at: datetime):Class 

lorsqu'il est utilisé en soi dans la méthode

def self.get_results(query, context) 
# ... 
end 

la erreur sera: méthode non définie gsub » pour nulle: NilClass dans la chaîne

query = ThinkingSphinx::Query.escape(query) 

Je suis un débutant ... mais je ne comprends pas .. SPHINX peut-être mal installé

Merci à l'avance!

+2

vous savez que vous ne nous montrez pas où vous utilisez le 'gsub' – MZaragoza

Répondre

1

Ce sont deux bogues différents. Le premier est que vous définissez une méthode d'instance, mais en l'utilisant sur la classe (et non sur une instance). Une méthode de classe commence self par exemple

def self.my_method_name 

et peut être appelé la classe principale, par exemple Search.my_method_name au lieu d'une instance spécifique de la classe de recherche. Un exemple d'appeler une méthode d'instance du même nom serait:

my_search = Search.new(:some => :attributes) 
my_search.my_method_name 

SO, votre premier message d'erreur vous dit « il n'y a pas de méthode appelée get_results la classe Search » - et cela est parce que vous avez défini comme def get_results au lieu de def self.get_results

Alors, alors vous avez essayé d'ajouter self. et cette erreur est partie.

Cela a ensuite exposé le prochain bug - qui est complètement indépendant du premier.

La deuxième erreur se produit lorsque vous appelez gsub sur zéro.

le gsub est probablement quelque chose se passe à l'intérieur de l'appel ThinkingSphinx::Query.escape(query).

et vous ne pouvez pas (facilement) changer quoi que ce soit à l'intérieur d'une autre bibliothèque ... mais vous pouvez toujours glaner des informations utiles à partir du message d'erreur. Dans ce cas, l'erreur est de se plaindre que vous appelez une méthode sur nil ... cela signifie que quelque chose est nil qu'elle s'attendait à être non-nul. Etant donné qu'il s'agit d'une requête de requête de recherche ... ma meilleure supposition serait qu'elle suppose que la variable query est une sorte de chaîne ... contenant une requête de recherche.

Il s'attend probablement à ce que la requête * NOT * soit nulle.

et pourtant dans ce cas il est.

si ...

a) quelqu'un frappe le bouton "go" sans entrer dans une recherche de requête?

b) vous avez fait une faute de frappe dans le nom du paramètre dans votre formulaire et que rien ne se passe réellement pour params[:query]?

c) l'imbrication de vos params est légèrement différent de ce que vous attendez (par exemple params[:search_form][:query])

Tout d'abord - vous devez double vérifier que vos formulaires envoient à travers le params que votre contrôleur attend réellement. Vous pouvez le faire en regardant dans les journaux -> soit dans la fenêtre du terminal/console, ou dans vos fichiers journaux (généralement log/development.log) et regarder ce qui se passe lorsque vous cliquez sur le bouton de soumission sur votre formulaire de recherche. Les journaux listeront les paramètres qui s'affichent lorsque vous soumettez ce formulaire et vous pouvez vérifier que c'est exactement ce que vous attendez. Deuxièmement: vous ne devriez probablement pas faire la recherche si aucune requête ne vient à travers - les gens vont accidentellement frapper le bouton soumettre même quand ils n'ont pas tapé quelque chose - et ce serait une interface graphique plus agréable si votre application n'a pas exploser quand cela arrive :)

Vous pouvez faire quelque chose comme ceci:

def self.get_results(query, context) 
    return nil unless query.present? 
    # ... the rest of the method here 
end 

assurez-vous que votre point de vue vérifie explicitement nul et n'explose pas dans ce cas.