Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveSupport::StringInquirer in Rails

I have a User model with status column. Rather than doing string comparison everytime like this

user.status == 'verified'

I though I should do

user.status.verified?

So I added following code

  def status
    ActiveSupport::StringInquirer.new(self.status)
  end

But now I am getting stack level too deep which is understandable. How do I fix this?

I am using Rails 3.2.

like image 958
Nick Vanderbilt Avatar asked Jan 06 '12 20:01

Nick Vanderbilt


3 Answers

Your problem is that you're calling status inside the status method, which causes an infinite recursion problem.

Most answers here focus on using ActiveSupport::StringInquirer initializer, like this:

def status
  return unless self['status']
  ActiveSupport::StringInquirer.new(self['status'])
end

But you don't need it. ActiveSupport adds an inquiry method to all strings, so you can do it like that:

def status
  self['status'].try(:inquiry)
end

This is the same as using read_attribute:

def status
  read_attribute(:status).try(:inquiry)
end

Or you can just call super:

def status
  super.try(:inquiry)
end
like image 61
joaomilho Avatar answered Nov 15 '22 22:11

joaomilho


Use the following code to prevent the "stack level too deep" error:

def status
  ActiveSupport::StringInquirer.new(self['status'])
end
like image 30
Baldrick Avatar answered Nov 15 '22 23:11

Baldrick


You may want to read the section "Overwriting default accessors" in ActiveRecord::Base's documentation: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Essentially you'll use read_attribute and write_attribute (or self['attribute'], like Baldrick pointed) to access the underlying attribute without calling the actual attribute accessor method.

like image 44
13k Avatar answered Nov 15 '22 23:11

13k