Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ruby on rails constantize method

I came across the following in the model:

class Search < ActiveRecord::Base
  #search different system user by dn
  def self.gets(sys, dn)
    sys.constantize.search(dn)
  end
end

I can see the purpose is to pass in different model name as sys and search by dn in those specific models. However, I searched on constantize in Ruby and couldn't see any detailed explanation about this usage.

like image 615
gkeepa Avatar asked Mar 08 '18 23:03

gkeepa


People also ask

Do you have the constantize method in your Rails codebase?

If you have the constantize method anywhere within your Rails codebase you are asking for trouble! This post looks at the most common usage of constantize, how constantize can be exploited, and a safe alternative to using it.

How does constantize () method work?

Tries to find a constant with the name specified in the argument string. For instance, if you have a model called Foo in your application, then you can apply the constantize method to a string, which contains the exact word Foo, and it'll give you a new object with this model.

What are string inflections in Ruby?

String inflections define new methods on the String class to transform names for different purposes. For instance, you can figure out the name of a table from the name of a class. Skip to ContentSkip to SearchMenu Close index Ruby on Rails 7.0.3.1 ClassString < Object

How does the method const_get work internally in Ruby?

Between the cases the method handles internally depending on what's being received as argument, you'll see the Object.const_get (string) which is the way Ruby (pure) handles a "constantiz-ation", which would be the same as doing.


2 Answers

Rails documentation (because constantize is a Rails method) says:

Tries to find a constant with the name specified in the argument string.

For instance, if you have a model called Foo in your application, then you can apply the constantize method to a string, which contains the exact word Foo, and it'll give you a new object with this model. Note this must be capitalized as Rails would work with your model, if you do a bad reference, then you'll get a NameError error:

NameError: wrong constant name foo

How does it do it?, if you go to the method definition, or if you playing with the method get an error, you'll see the source points to activesupport-5.1.5/lib/active_support/inflector/methods.rb:269:in 'const_get', which is the method definition and the error source.

Between the cases the method handles internally depending on what's being received as argument, you'll see the Object.const_get(string) which is the way Ruby (pure) handles a "constantiz-ation", which would be the same as doing

Object.const_get('Foo') # Foo(...)
Object.const_get('foo') # NameError: wrong constant name foo

If thinking on implement this handy method, you could take a look to the Gavin Miller's post from some years ago.

like image 145
Sebastian Palma Avatar answered Oct 22 '22 17:10

Sebastian Palma


When I type 'foo'.constantize in my editor (RubyMine) and tap Ctrl+B, it takes me to the source, .../activesupport-4.2.8/lib/active_support/core_ext/string/inflections.rb, with this comment:

# +constantize+ tries to find a declared constant with the name specified
# in the string. It raises a NameError when the name is not in CamelCase
# or is not initialized.  See ActiveSupport::Inflector.constantize
#
#   'Module'.constantize  # => Module
#   'Class'.constantize   # => Class
#   'blargle'.constantize # => NameError: wrong constant name blargle
def constantize
  ActiveSupport::Inflector.constantize(self)
end

It probably eventually calls Object.get_const(). I recommend you get a better editor, with code browsing, and you start learning your way around the Rails source code.

like image 37
Phlip Avatar answered Oct 22 '22 16:10

Phlip