14b8667b3bdf64068647b96c26001e0d

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.

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 !

70ca58d0e0e0eabbdb74d177417d09d7

leethal

April 7, 2008, April 07, 2008 09:55, permalink

1 rating. Login to rate!

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
70ca58d0e0e0eabbdb74d177417d09d7

leethal

April 7, 2008, April 07, 2008 09:56, permalink

No rating. Login to rate!

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
5170ca260dbd2cdfd5a887a4dba7636f

Jeremy Weiskotten

April 8, 2008, April 08, 2008 00:24, permalink

1 rating. Login to rate!

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

Your refactoring





Format Copy from initial code

or Cancel