Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
class Race < ActiveRecord::Base before_validation :set_abbreviation # Associations has_one :employee # Validatioins validates_presence_of :name, :abbreviation validates_uniqueness_of :name, :abbreviation protected # The method will generate an unambiguous abbreviatioin from the model's name attribute and assign it to the models abbreviation attribute def set_abbreviation name = self.name.to_s strnlength = name.size while strnlength >= 3 do chop.name strnlength = name.size end if name.size == 3 self.abbreviation = name.capitalize else raise "While loop failed to produce a viable abbreviation" end end end
Refactorings
No refactoring yet !
leethal
April 7, 2008, April 07, 2008 09:55, permalink
I'd just use the first characters of each of the persons name. Wouldn't care about the size, really, most people have between 2 and 4 names anyway.
1 2 3
def set_abbreviation self.abbreviation = full_name.split(" ").map {|name| name[0].chr }.join end
leethal
April 7, 2008, April 07, 2008 09:56, permalink
I'd just use the first characters of each of the persons name. Wouldn't care about the size, really, most people have between 2 and 4 names anyway.
1 2 3
def set_abbreviation self.abbreviation = full_name.split(" ").map {|name| name[0].chr }.join end
Jeremy Weiskotten
April 8, 2008, April 08, 2008 00:24, permalink
The problem is with chop.name. You should have name.chop. However, here's a more extensive refactoring. Note that instead of raising an error in the set_abbreviation method this version validates that the length of name is >= 3 with validates_length_of.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
class Race < ActiveRecord::Base before_validation :set_abbreviation # Associations has_one :employee # Validations validates_presence_of :name, :abbreviation validates_uniqueness_of :name, :abbreviation validates_length_of :name, :minimum => 3 validates_length_of :abbreviation, :is => 3 protected # The method will generate an unambiguous abbreviation from the model's name attribute and assign it to the models abbreviation attribute def set_abbreviation self.abbreviation = name[0,3].upcase end end
Hi all,
I am attempting to utilize Rails' callback hooks to run a custom function on an instance of a model. Originally I had the abbreviation assigned to the model through a form (i.e. the user would assign an abbreviation and the time of creation); however I'd like to just generate one automatically before validations occur so that I can control the format. here is what I have so far, but from the console I get a "TypeError: $_ value need to be String (nil given)" for chop. Any ideas or recommendations would be greatly appreciated.