Reputation: 2847
The Model is:
class Persona < ActiveRecord::Base
before_save :make_downcase_name
after_initialize :make_downcase_name
validates :name, presence: true, length: { maximum: 50 }
validates :downcase_name, uniqueness: { case_sensitive: false }
private
def make_downcase_name
if name != nil
self.downcase_name ||= name.downcase
end
end
end
This test fails:
before do
@persona = Persona.new(name: "Bazman")
end
subject { @persona }
describe "name with mixed case" do
let(:mixed_case_name) { "TeRRy" }
it "should be saved as all lower-case" do
@persona.name = mixed_case_name
@persona.save
expect(@persona.reload.downcase_name).to eq mixed_case_name.downcase
end
end
with the error message:
expected: "terry"
got: "bazman"
So that means in the test when @persona.save is called, the before_save callback is not changing TeRRy's downcase_name to terry, so the line
self.downcase_name ||= name.downcase
is failing, but I don't understand why.
Upvotes: 0
Views: 34
Reputation: 18682
downcase_name
is not updated to the lowercase version of the new name because of the way make_downcase_name
works.
self.downcase_name ||= name.downcase
This line can be explained as: if downcase_name
is falsey (nil
or false
), then set it to name.downcase
. Otherwise, leave it alone.
There are two options here. Either your spec is right and downcase_name
should be updated when a new name is assigned, or your model is right and downcase_name
should never change once it has first been assigned.
In this case, you need to fix your model:
def make_downcase_name
return unless name
self.downcase_name = name.downcase
end
That's it!
If this is true, you need to make sure you're creating a new Persona
in your spec. First, let's do a small refactoring of your spec to declare variables using let
rather than using an instance variable:
let(:persona) { Persona.new(name: 'Bazman' }
subject { persona }
describe "name with mixed case" do
let(:mixed_case_name) { "TeRRy" }
it "should be saved as all lower-case" do
persona.name = mixed_case_name
persona.save
expect(persona.reload.downcase_name).to eq mixed_case_name.downcase
end
end
For the name with mixed case
scenario, you can now easily create a new Persona
instance:
let(:persona) { Persona.new(name: 'Bazman') }
subject { persona }
describe "name with mixed case" do
let(:mixed_case_name) { "TeRRy" }
let(:persona) { Persona.new }
it "should be saved as all lower-case" do
persona.name = mixed_case_name
persona.save
expect(persona.downcase_name).to eq mixed_case_name.downcase
end
end
Upvotes: 1