我正在尝试挑战,我需要做一些验证。我应该通过以下测试:
it 'should not allow political words' do
body = "Petralha Tucanos Dilma"
opinion = Opinion.new(body: body)
expect(opinion).to_not be_valid
expect(opinion.errors[:body]).to include "Contains political words"
end
it 'is invalid when has no body' do
body = ''
opinion = Opinion.new(body: body)
expect(opinion).to_not be_valid
expect(opinion.errors[:body]).to include 'can\'t be blank'
end
it 'is invalid when has more than 150 caracters' do
body = 'a' * 151
opinion = Opinion.new(body: body)
expect(opinion).to_not be_valid
expect(opinion.errors[:body]).to include 'is too long'
end
为此,我在我的模型上尝试了以下内容:
class Opinion < ActiveRecord::Base
validates :body, presence: true, length: { maximum: 150 }, exclusion: { in: %w(Petralha Tucanos Dilma) }
end
我仍然是Rails的菜鸟,所以任何人都有线索? 这些是我得到的错误:
1)意见不应该允许政治话语 失败/错误:期望(意见).to_not be_valid 预期#不是有效的 #./spec/models/opinion_spec.rb:16:in块中的“块(2级)”
2)当有超过150个字符时,意见无效 失败/错误:期望(opinion.errors [:body])。包含&#39;太长&#39; 预期[&#34;太长(最多150个字符)&#34;]包括&#34;太长&#34; #./spec/models/opinion_spec.rb:33:in块中的“块(2级)”
在0.12861秒内完成(文件加载时间为0.64205秒) 11个例子,2个失败
失败的例子:
rspec ./spec/models/opinion_spec.rb:12#意见不应该允许政治话语 rspec ./spec/models/opinion_spec.rb:28#当有超过150个字符时,意见无效
答案 0 :(得分:0)
您的验证不起作用,因为排除与整个字符串的值匹配,只有这样:
class Opinion < ActiveRecord::Base
validates :a_single_word, exclusion: { in: %w(foo bar baz) }
end
@opinion.a_single_word = "tuna"
@opinion.valid? == true
@opinion.a_single_word = "I'm saying foo and bar and baz"
@opinion.valid? == true
@opinion.a_single_word = "foo"
@opinion.valid? == false
解决此问题的一种基本方法是使用检查整个正文字符串的正则表达式,如果表达式找到匹配项,则返回false。这看起来像这样,使用negative lookaround并在此处提供而未经过测试:
class Opinion < ActiveRecord::Base
POLITICAL_WORDS_REGEX = \A((?!Petralha|Tucanos|Dilma).)*\z
validates :body, ..., format: { with: POLITICAL_WORDS_REGEX }
end
一个可能更好的解决方案是使用像Obscenity这样的亵渎性过滤宝石,看起来它可以让你定义一个政治词汇词典并自定义验证错误。