Module: ActiveRecord::Extensions
- Extended by:
- Forwardable
- Defined in:
- lib/ar-extensions/version.rb,
lib/ar-extensions/extensions.rb,
lib/ar-extensions/create_and_update.rb,
lib/ar-extensions/util/sql_generation.rb,
lib/ar-extensions/util/support_methods.rb
Overview
ActiveRecord::Extensions provides additional functionality to the ActiveRecord ORM library created by DHH for Rails.
It’s main features include:
-
better finder support using a :conditions Hash for ActiveRecord::Base#find
-
better finder support using any object that responds to the to_sql method
-
mass data import functionality
-
a more modular design to extending ActiveRecord
Using Better Finder Hash Support
Here are a few examples, please refer to the class documentation for each extensions:
class Post < ActiveRecord::Base ; end
Post.find( :all, :conditions=>{
:title => "Title", # title='Title'
:author_contains => "Zach", # author like '%Zach%'
:author_starts_with => "Zach", # author like 'Zach%'
:author_ends_with => "Dennis", # author like '%Zach'
:published_at => (Date.now-30 .. Date.now), # published_at BETWEEN xxx AND xxx
:rating => [ 4, 5, 6 ], # rating IN ( 4, 5, 6 )
:rating_not_in => [ 7, 8, 9 ] # rating NOT IN( 4, 5, 6 )
:rating_ne => 4, # rating != 4
:rating_gt => 4, # rating > 4
:rating_lt => 4, # rating < 4
:content => /(a|b|c)/ # REGEXP '(a|b|c)'
)
Create Your Own Finder Extension Example
The following example shows you how-to create a robust and reliable finder extension which allows you to use Ranges in your :conditions Hash. This is the actual implementation in ActiveRecord::Extensions.
class RangeExt
NOT_IN_RGX = /^(.+)_(ne|not|not_in|not_between)$/
def self.process( key, val, caller )
return nil unless val.is_a?( Range )
match_data = key.to_s.match( NOT_IN_RGX )
key = match_data.captures[0] if match_data
fieldname = caller.connection.quote_column_name( key )
min = caller.connection.quote( val.first, caller.columns_hash[ key ] )
max = caller.connection.quote( val.last, caller.columns_hash[ key ] )
str = "#{caller.quoted_table_name}.#{fieldname} #{match_data ? 'NOT ' : '' } BETWEEN #{min} AND #{max}"
Result.new( str, nil )
end
Using to_sql Ducks In Your Find Methods!
The below example shows you how-to utilize objects that respond_to the method to_sql
in your finds:
class InsuranceClaim < ActiveRecord::Base ; end
class InsuranceClaimAgeAndTypeQuery
def to_sql
"age_in_days BETWEEN 1 AND 60 AND claim_type IN( 'typea', 'typeb' )"
end
end
claims = InsuranceClaim.find( :all, InsuranceClaimAgeAndTypeQuery.new )
claims = InsuranceClaim.find( :all, :conditions=>{
:claim_amount_gt => 30000,
:age_and_type => InsuranceClaimAgeAndTypeQuery.new }
)
Importing Lots of Data
ActiveRecord executes a single INSERT statement for every call to ‘create’ and for every call to ‘save’ on a new model object. When you have only a handful of records to create or save this is not a big deal, but when you have hundreds, thousands or hundreds of thousands of records you need to have better performance.
Below is an example of how to import the least amount of INSERT statements using mechanisms provided by your database vendor:
class Student < ActiveRecord::Base ; end
column_names = Student.columns.map{ |column| column.name }
value_sets = some_method_to_load_data_from_csv_file( 'students.csv' )
= { :valudate => true }
Student.import( column_names, value_sets, )
The import
functionality can be used even if there is not specific support for you vendor. This happens when a particular database vendor specific enhancement hasn’t been added to ActiveRecord::Extensions. You can still use import
though because the import
functionality has been created with backwards compatibility. You may still get better performance using import
, but you will definitely get no worse then ActiveRecord’s create or save methods.
See ActiveRecord::Base.import for more information and other ways to use this functionality.
Developers
-
Zach Dennis
-
Mark Van Holsytn
Homepage
-
Project Site: www.continuousthinking.com/tags/arext
-
Rubyforge Project: rubyforge.org/projects/arext
-
Anonymous SVN: svn checkout svn://rubyforge.org/var/svn/arext
Defined Under Namespace
Modules: ConnectionAdapters, CreateAndUpdate, Delete, FindToCSV, FinderOptions, ForeignKeys, FullTextSearching, Import, InsertSelectSupport, SqlGeneration, SupportMethods, TemporaryTableSupport, Union, VERSION Classes: ArrayExt, Comparison, DatetimeSupport, Like, MySQLRegexp, OracleRegexp, PostgreSQLRegexp, RangeExt, RegexpBase, Registry, Result, SqliteRegexp