0

Im trying a challenge where I need to do some validations. I should pass on the following tests:

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

To do so I tried the following on my model:

class Opinion < ActiveRecord::Base
  validates :body, presence: true, length: { maximum: 150 }, exclusion: { in: %w(Petralha Tucanos Dilma) }
end

Im still a noob on Rails, so anyone have a clue? Those are the errors I get:

1) Opinion should not allow political words Failure/Error: expect(opinion).to_not be_valid expected # not to be valid # ./spec/models/opinion_spec.rb:16:in `block (2 levels) in '

2) Opinion is invalid when has more than 150 caracters Failure/Error: expect(opinion.errors[:body]).to include 'is too long' expected ["is too long (maximum is 150 characters)"] to include "is too long" # ./spec/models/opinion_spec.rb:33:in `block (2 levels) in '

Finished in 0.12861 seconds (files took 0.64205 seconds to load) 11 examples, 2 failures

Failed examples:

rspec ./spec/models/opinion_spec.rb:12 # Opinion should not allow political words rspec ./spec/models/opinion_spec.rb:28 # Opinion is invalid when has more than 150 caracters

Beartech
  • 5,302
  • 1
  • 15
  • 35
Aram
  • 3
  • 4
  • 2
    I edited your question to format the code so it will show correctly and use syntax highlighting. In the future use the code button "{}" or add 4 spaces to the beginning of each new line of code (beyond any indentation). – Beartech Nov 26 '15 at 01:04

1 Answers1

0

Your validation doesn't work because exclusion matches against the value of the entire string, which only works like this:

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

One basic way to approach this is to use a regular expression that checks the whole body string and returns false if the expression finds a match. This would look something like this, which uses a negative lookaround and is provided here without being tested:

class Opinion < ActiveRecord::Base
  POLITICAL_WORDS_REGEX = \A((?!Petralha|Tucanos|Dilma).)*\z

  validates :body, ..., format: { with: POLITICAL_WORDS_REGEX }
end

A potentially better solution would be to use a profanity filtering gem like Obscenity, which looks like it will let you define a dictionary of political words and customize validation errors.

Community
  • 1
  • 1
Brent Eicher
  • 1,010
  • 9
  • 14