Chris Valentine
Chris Valentine

Reputation: 1637

Rails Model method check if field nil, if so return empty string

In my model class I have a method:

def full_address
    address_lines = [self.address1,self.address2,self.address3].reject!(&:empty?).join(',')
    fulladdress = address_lines + ", " + self.city + ', ' + self.state  + ', ' + self.zipcode
    return fulladdress 
end

This is just an easy way to return all the address fields to view them quickly.

This returns undefined method 'empty?' for nil:NilClasswhen its empty. How can I change the method to work if all address1, address2, address3 are empty?

I guess I'm looking for a function like:

ReturnBlankIfNilElseValue(self.address1)

Anything like that exist?

def full_address
    address_lines = [self.address1.to_s,self.address2.to_s,self.address3.to_s].reject!(&:empty?).join(',')
    fulladdress = address_lines + ", " + self.city + ', ' + self.state  + ', ' + self.zipcode
    return fulladdress 
end

This variation returns no implicit conversion of nil into String which is odd because in rails console i can type nil.to_s and get an empty string.

I don't really want to check if each field is nil and then add to the array, i'd prefer a function that just returned empty string if it is nil.

Sorry the nil.to_s does work its the 2nd line that needed one as well. Its working now will get rid of this.

Upvotes: 0

Views: 3588

Answers (3)

Myst
Myst

Reputation: 19221

You can, although this might not be what you wanted, simply remove any nil objects from the address Array using the #compact method, so that #empty? will work...:

def full_address
    [self.address1, self.address2, self.address3,
        self.city, self.state, self.zipcode].compact.reject!(&:empty?).join(', ')
end

You should be aware that this WILL return a partial address if SOME of the fields exist.

I would probably void any fault addresses (in this example I require just the first address line and the city fields):

def full_address
    return "" unless self.address1 && self.city && !self.address1.empty? && !self.city.empty? 
    [self.address1, self.address2, self.address3,
        self.city, self.state, self.zipcode].compact.reject!(&:empty?).join(', ')
end

Disregarding the few edits I made to the code, I would probably go with @Joseph's #present? together with the validation, since you're using Rails:

def full_address
    return "" unless self.address1 && self.city && self.address1.present? && self.city.present? 
    [self.address1, self.address2, self.address3,
        self.city, self.state, self.zipcode].reject!(&:present?).join(', ')
end

Upvotes: 1

Joseph
Joseph

Reputation: 760

You can use present? to check for nil without throwing an error (it returns false for nil and for empty string or a string with just spaces in it).

So, instead of using reject and empty?, you can use select and present?.

    address_lines = [self.address1,self.address2,self.address3].select(&:present?).join(',')

This won't return an empty string for blank or nil addresses -- it will just leave them out of address_lines.

Note present? is the opposite of blank? suggested by chad_. I think either one will help you get the result you need.

Decent summary on this blog: http://railsless.blogspot.com/2011/08/difference-between-nil-empty-blank.html

Upvotes: 2

chad_
chad_

Reputation: 3819

In rails, you can check foo.blank? and it will check nil? || empty

Upvotes: 1

Related Questions