How to Use Active Support Core Extensions

How to use Active Support core extensions

Since using Rails should handle this automatically I'm going to assume you're trying to add Active Support to a non-Rails script.

Read "How to Load Core Extensions".

Active Support's methods got broken into smaller groups in Rails 3, so we don't end up loading a lot of unneeded stuff with a simple require 'activesupport'. Now we have to do things like

require 'active_support/core_ext/object/blank'

If you don't care about granularity, you can choose to load bigger chunks. If you want everything in one big gulp use...

For 1.9.2:

rvm 1.9.2
irb -f
irb(main):001:0> require 'active_support/all'
=> true
irb(main):002:0> 1.week.ago
=> 2010-11-14 17:56:16 -0700
irb(main):003:0>

For 1.8.7:

rvm 1.8.7
irb -f
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'active_support/all'
=> true
irb(main):003:0> 1.week.ago
=> Sun Nov 14 17:54:19 -0700 2010
irb(main):004:0>

how to use active support core ext date and time

Those modules date_and_time are there because they are modules that are included by all of the Date, Time and DateTime core extensions. Those modules extend those classes with the same methods. Hence they are grouped under Date and Time, because you get the same new methods across all classes.

So, they are modules, meant to be included as extensions. You cannot require them separately and expect new functionality, unless you are meaning to use them to extend class functionality through include.

Here's an example directly from the Rails source on how it's used (taken from core_ext/date/calculations in this case):

require "active_support/core_ext/date_and_time/calculations"

class Date
include DateAndTime::Calculations
...
end

You can look at the source yourself, or check out the docs for the added methods.

For example, with that extension in both Date and Time, you can now do:

Time.now.last_year
Date.today.last_year

Same method is available, for both classes.

How to use Rails 3's ActiveSupport core extensions outside Rails

ActiveSupport is more separate now in Rails 3.

If you want the all active_support thing, you can require 'active_support/all' now.

But if you want only the blank? method, you can try

require 'active_support/core_ext/string'

trying to require active_support in gem

You need to require the methods you need from ActiveSupport; they aren't added by default.

As Yevgeniy mentioned in a comment, the way to do this is require 'active_support/all' if you need everything - or if, for example, you want only the Hash extensions then use require 'active_support/core_ext/hash'. Note that this usually doesn't go in the gemspec, but rather in whatever file your gem uses to set itself up.

Perhaps even better would be to require the required ActiveSupport files in the actual files needing them, but that's a matter of taste.

why can I require 'active_support/core_ext'?

Look for the file named core_ext.rb.

But no require can't load directories.

Including Rails time helpers in a non-Rails Ruby application

These methods come from ActiveSupport's core extensions (specifically ones on Integer & Numeric), so you can just require them:

require 'active_support/core_ext/integer/time'
require 'active_support/core_ext/numeric/time'

Or if you want all core extensions ActiveSupport provides:

require 'active_support/core_ext'

Or if you want all of ActiveSupport (core extensions included):

require 'active_support/all'

Of course you have to ensure the activesupport gem is installed.

Overriding an active support method with a ruby refinement

Thanks to Lam Phan comment, it's not possible via a refinement unfortunately.

However I was able to do it by override the default timestamp format.

# save previous default value
previous_default = ::Time::DATE_FORMATS[:default]

# set new default to be the utc timezone with iso8601 format
::Time::DATE_FORMATS[:default] = proc { |time| time.utc.iso8601(6) }

puts JSON.pretty_generate(User.last.as_json(only: [:created_at]))

# set the default back if we have one
if previous_default.blank?
::Time::DATE_FORMATS.delete(:default)
else
::Time::DATE_FORMATS[:default] = previous_default
end

Why use ActiveSupport::Concern instead of just a plain module?

From https://api.rubyonrails.org/classes/ActiveSupport/Concern.html:

A typical module looks like this:

module M
def self.included(base)
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end

module ClassMethods
...
end
end

By using ActiveSupport::Concern the above module could instead be written as:

require 'active_support/concern'

module M
extend ActiveSupport::Concern

included do
scope :disabled, -> { where(disabled: true) }
end

class_methods do
...
end
end

Moreover, it gracefully handles module dependencies. Given a Foo module and a Bar module which depends on the former, we would typically write the following:

module Foo
def self.included(base)
base.class_eval do
def self.method_injected_by_foo
...
end
end
end
end

module Bar
def self.included(base)
base.method_injected_by_foo
end
end

class Host
include Foo # We need to include this dependency for Bar
include Bar # Bar is the module that Host really needs
end

But why should Host care about Bar's dependencies, namely Foo? We could try to hide these from Host directly including Foo in Bar:

module Bar
include Foo
def self.included(base)
base.method_injected_by_foo
end
end

class Host
include Bar
end

Unfortunately this won't work, since when Foo is included, its base is the Bar module, not the Host class. With ActiveSupport::Concern, module dependencies are properly resolved:

require 'active_support/concern'

module Foo
extend ActiveSupport::Concern
included do
def self.method_injected_by_foo
...
end
end
end

module Bar
extend ActiveSupport::Concern
include Foo

included do
self.method_injected_by_foo
end
end

class Host
include Bar # It works, now Bar takes care of its dependencies
end


Related Topics



Leave a reply



Submit