2010-08-28 83 views
0

我正在制作一个Web应用程序,其中的重点是要将给定的单词改为一个字母。例如,如果我通过选择单词“最好”来发表帖子,那么第一个答复可以是“休息”,而之后的答复应该是“出租”,“发送”等。因此,用户这个词输入必须由最后提交的单词的一个字母改变。它会不断发展。自定义验证Rails应用程序的麻烦

现在你可以制作一款游戏,只需输入一个词就可以做出回应。我编写了使用功能,从Amatch宝石定义验证:

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

帖子有很多反应,反应属于职务。

下面的代码:

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 

当我试图进入一个测试后我做了一个新的响应(原词“最好的”,第一反应就是“休息”)我得到这样的:

ActiveRecord :: RecordInvalid在ResponsesController#create 验证失败:对不起,您必须将上一次提交的单词更改为一个字母

对可能出错的想法有何想法? 谢谢!

+0

该方法有单元测试吗? – Reactormonk 2010-08-28 14:13:05

回答

1

看起来像这里有几个潜在的问题。

例如,您的if声明实际上与您的errors.add_to_base...声明不同吗?如果是这样,你的语法是错误的; if语句需要与它正在修改的语句位于同一行。即使它实际上是在正确的路线上,我也不建议在这么长的路线上使用尾随的if声明;这将使它很难找到条件。

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 

其次,对浮点数进行精确的相等比较几乎不是一个好主意。因为浮点数涉及近似值,所以有时您会得到与您正在比较的给定数非常接近但不完全相等的结果。它看起来像Amatch库有几个不同的类来比较字符串;卖家类允许你为不同类型的编辑设置不同的权重,但考虑到你的问题描述,我不认为你需要这样做。我会尝试使用LevenshteinHamming距离,取决于您的确切需求。

最后,如果这些建议都不起作用,请尝试向日志或回复中写入title.strippost.responses.last.to_s.strip的确切值,以确保您实际比较了您认为正在比较的值。我不知道你的代码的其余部分,所以我不能告诉你这些代码是否正确,但是如果你将它们打印出来,你应该很容易自己检查它们。

+0

感谢Brian,帮助。我相信我把if语句放在同一行上,但是我认为当我点击提交时它会被破坏。 海明距离似乎是一个更好的匹配。感谢这些建议。 在控制台中: post = Post.find_by_id(1) post.responses.last。to_s =>“#<响应:0x103275db8>” 这就是问题所在。它没有比较实际的最后一个响应文本,而是对象ID。所以我删除了to_s并将其替换为Response属性的标题属性: post.responses.last.title 我认为这样做。感谢您带领我走向正确的方向! – dartfrog 2010-08-28 17:27:46