我的验证怎么了?

时间:2015-11-26 00:23:47

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

我正在尝试挑战,我需要做一些验证。我应该通过以下测试:

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个字符时,意见无效

1 个答案:

答案 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这样的亵渎性过滤宝石,看起来它可以让你定义一个政治词汇词典并自定义验证错误。