2010-08-28 4 views
0

Je crée une application Web dont le but est de modifier un mot donné par une lettre. Par exemple, si je fais un post en sélectionnant le mot: "meilleur", alors la première réponse pourrait être "repos", tandis que celle après cela devrait être "louer", "envoyé", etc. Ainsi, le mot un utilisateur entre doit avoir changé d'une lettre du dernier mot soumis. Il serait en constante évolution.Problème avec la validation personnalisée de l'application Rails

À l'heure actuelle, vous pouvez créer un jeu et répondre simplement en tapant un mot. Je codé une validation personnalisée en utilisant la fonctionnalité de la gemme amatch:

http://flori.github.com/amatch/doc/index.html

postes ont beaucoup de réponses, et les réponses appartiens à un poste.

est ici le code:

def must_have_changed_by_one_letter 
     m = Amatch::Sellers.new(title.strip) 
     errors.add_to_base("Sorry, you must change the last submitted word by one letter") 
     if m.match(post.responses.last.to_s.strip) != 1.0 
    end 

Quand je reçois ce que j'essaie d'inscrire une nouvelle réponse pour un poste de test j'ai fait (mot d'origine « meilleur », la première réponse est « repos »):

ActiveRecord :: RecordInvalid dans ResponsesController # create La validation a échoué: Désolé, vous devez modifier le dernier mot soumis par une lettre

Des idées sur ce qui pourrait ne pas fonctionner? Merci!

+0

Avez-vous obtenu des tests unitaires pour cette méthode? – Reactormonk

Répondre

1

On dirait qu'il y a quelques problèmes potentiels ici.

Par exemple, votre instruction if est-elle réellement sur une ligne distincte de votre instruction errors.add_to_base...? Si oui, votre syntaxe est erronée; l'instruction if doit être dans la même ligne que l'instruction modifiée. Même si elle est réellement sur la ligne correcte, je recommanderais de ne pas utiliser une instruction if sur une ligne aussi longue; il sera difficile de trouver le conditionnel. Deuxièmement, faire une comparaison exacte de l'égalité sur les nombres à virgule flottante n'est presque jamais une bonne idée. Comme les nombres à virgule flottante impliquent des approximations, vous obtiendrez parfois des résultats très proches, mais pas tout à fait égaux, d'un nombre donné avec lequel vous comparez. Il semble que la bibliothèque Amatch a plusieurs classes différentes pour comparer les chaînes; la classe Sellers vous permet de définir des poids différents pour différents types de modifications, mais étant donné la description de votre problème, je ne pense pas que vous en ayez besoin. J'utiliserais plutôt la distance Levenshtein ou Hamming, en fonction de vos besoins précis. Enfin, si aucune de ces suggestions ne fonctionne, essayez d'écrire dans un journal ou dans la réponse les valeurs exactes de title.strip et post.responses.last.to_s.strip, pour vous assurer que vous comparez réellement les valeurs que vous pensez comparer. Je ne connais pas le reste de votre code, donc je ne peux pas vous dire si elles sont correctes ou non, mais si vous les imprimez quelque part, vous devriez facilement pouvoir les vérifier vous-même.

+0

Merci Brian, ça m'a aidé. Je crois que j'ai mis la déclaration if sur la même ligne, mais je suppose que ça a été bousculé quand j'ai frappé submit. La distance de Hamming semble être un meilleur match. Merci pour ces recommandations. Dans la console: post = Post.find_by_id (1) post.responsesto_s => "# " Voilà où était le problème. Il ne comparait pas le texte de la dernière réponse, mais l'identifiant de l'objet. Donc j'ai enlevé le to_s et l'ai remplacé par l'attribut title de la réponse: post.responses.last.title Je pense que cela a fait l'affaire. Merci de m'avoir conduit dans la bonne direction! – dartfrog

Questions connexes