Orginal Question
This is a really horrible method, which checks for equality on base of the code but case agnostic
def ==(another_country)
(code.nil? ? nil : code.downcase) == (another_country.code.nil? ? nil : another_country.code.downcase) unless another_country.nil?
end
Can you point my in the right direction how to write this more elegant w/o reliying on ugly if else structures?
This is the solution I ended up using (+RSpecs)
# Country model
class Country < ActiveRecord::Base
attr_accessible :code
def ==(another_country)
code.to_s.downcase == another_country.code.to_s.downcase rescue false
end
end
Extensive Tests:
# RSpec
describe Country do
describe 'equality based solely on Country.code' do
before do
@country_code_de = FactoryGirl.build(:country, :code => 'de')
end
it 'should be equal if Country.code is equal' do
other_country_code_de = FactoryGirl.build(:country, :code => 'de')
@country_code_de.should == other_country_code_de
end
it 'should be not equal if Country.code is not equal' do
country_code_usa = FactoryGirl.build(:country, :code => 'usa')
@country_code_de.should_not == country_code_usa
end
it 'should be case insensitive' do
country_code_de_uppercase = FactoryGirl.build(:country, :code => 'DE')
@country_code_de.should == country_code_de_uppercase
end
it 'should not rely on id for equality' do
@country_code_de.id = 0
country_code_usa = FactoryGirl.build(:country, :code => 'usa', :id => 0)
@country_code_de.should_not == country_code_usa
end
it 'should be not equal if Country.code of one Country is nil' do
country_code_nil = FactoryGirl.build(:country, :code => nil)
@country_code_de.should_not == country_code_nil
end
it 'should be equal if Country.code for both countries is nil' do
country_code_nil = FactoryGirl.build(:country, :code => nil)
other_country_code_nil = FactoryGirl.build(:country, :code => nil)
country_code_nil.should == other_country_code_nil
end
it 'should be not equal if other Country is nil' do
@country_code_de.should_not == nil
end
it 'should be not equal if other object is not a Country' do
@country_code_de.should_not == 'test'
end
it 'should be equal for descendants of Country with same Country.code' do
class CountryChild < Country
end
country_child = CountryChild.new(:code => 'de')
@country_code_de.should == country_child
end
end
end