dartfrog
dartfrog

Reputation: 91

Trouble with custom validation of Rails app

I'm making a web app where the point is to change a given word by one letter. For example, if I make a post by selecting the word: "best," then the first reply could be "rest," while the one after that should be "rent," "sent", etc. So, the word a user enters must have changed by one letter from the last submitted word. It would be constantly evolving.

Right now you can make a game and respond just by typing a word. I coded up a custom validation using functionality from the Amatch gem:

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

Posts have many responses, and responses belong to a post.

here's the 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

When I try entering a new response for a test post I made (original word "best", first response is "rest") I get this:

ActiveRecord::RecordInvalid in ResponsesController#create Validation failed: Sorry, you must change the last submitted word by one letter

Any thoughts on what might be wrong? Thanks!

Upvotes: 0

Views: 112

Answers (1)

Brian Campbell
Brian Campbell

Reputation: 333294

Looks like there are a couple of potential issues here.

For one, is your if statement actually on a separate line than your errors.add_to_base... statement? If so, your syntax is wrong; the if statement needs to be in the same line as the statement it's modifying. Even if it is actually on the correct line, I would recommend against using a trailing if statement on such a long line; it will make it hard to find the conditional.

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

Second, doing exact equality comparison on floating point numbers is almost never a good idea. Because floating point numbers involve approximations, you will sometimes get results that are very close, but not quite exactly equal, to a given number that you are comparing against. It looks like the Amatch library has several different classes for comparing strings; the Sellers class allows you to set different weights for different kinds of edits, but given your problem description, I don't think you need that. I would try using the Levenshtein or Hamming distance instead, depending on your exact needs.

Finally, if neither of those suggestions work, try writing out to a log or in the response the exact values of title.strip and post.responses.last.to_s.strip, to make sure you are actually comparing the values that you think you're comparing. I don't know the rest of your code, so I can't tell you whether those are correct or not, but if you print them out somewhere, you should be easily able to check them yourself.

Upvotes: 1

Related Questions