Main question
This is a really terrible method that checks for equality based on code, but not 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 me in the right direction, how to write it more elegantly, without relying on ugly, if still structures?
This is the solution as a result of which I used (+ 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
source share