ActiveRecord::Extensions 0.7.0 Released!
on July 21, 2007 @ 06:37 AM
ActiveRecord::Extensions 0.7.0 is released! Thanks to Michael Flester and Gabe da Silveira for the patches they submitted!
Updates include:
- Oracle support for better finders (but regexps only work with Oracle 10 or higher) and import (Michael Flester)
- created_at/updated_at timestamps are now implemented with import functionality if they exist on the tables (Zach Dennis/Michael Flester)
- fixed padding issue with MySQL by increasing the byte buffer size to 8 bytes. (thanks to Gabe da Silveira)
To install as a gem you can run:
gem install ar-extensions
To update a previously installed gem you can run:
gem update ar-extensions
To install as a script/plugin you can run:
script/plugin install http://arext.rubyforge.org/svn/tags/ar-extensions-0.7.0
To see information on the usage of ar-extensions please refer to the arext page or refer to the RDOC documentation
Enjoy!
For questions, comments please feel free to email me, zach dot dennis at gmail dot com or by submitting to rubyforge project page for arext.
acts_as_comparable 1.2 released
on June 30, 2007 @ 08:55 PM
acts_as_comparable 1.2 has been released with a minor update. This includes a fix to handling additional options passed into the declarative acts_as_comparable call.
For example with acts_as_comparable 1.1:
1 2 3 4 5 6 7 8 9 |
# this works class Model < ActiveRecord::Base acts_as_comparable end # the options passed in are ignored. class Model < ActiveRecord::Base acts_as_comparable :except => [:id, :name] end |
Now in 1.2 this is fixed so you can pass the following options make calls like:
1 2 3 |
acts_as_comparable acts_as_comparable :only=>[:first_name, :last_name] acts_as_comparable :except => [:id, :name] |
Installing as a RubyGem
gem install -r acts_as_comparable |
Installing as a Plugin
Installing from a version
1 2 |
script/plugin install \ http://rails.lotswholetime.com/svn/acts_as_comparable/tags/acts_as_comparable-1.2 |
Rails patch 8277
on May 06, 2007 @ 05:11 AM
The synchronize functionality released in ActiveRecord::Extensions 0.6.0 should probably go in core. So I submitted a patch
My reasoning is that is ActiveRecord::Base#reload already works on a per instance level, why not allow it work on a class level where the class can efficiently handle reloads on multiple instances at once.
The benefit of the class level reload is that you can do one query to the database regardless of how many instances you have rather then having to perform one query per instance.
If you’re in favor of the patch please encourage it gets accepted.
ActiveRecord::Extensions 0.6.0 released
on May 06, 2007 @ 04:34 AM
ActiveRecord::Extensions 0.6.0 is released! You can install it via RubyGems:
gem install ar-extensions |
What’s New?
0.6.0 includes:- support for arrays when using the Hash arguments and the ‘_contains’ suffix.
- a synchronize method which acts like ActiveRecord::Base#reload, but it works on multiple instances. The benefit being that it makes one query to reload all instances rather then one query per instance
- a bug fix for URI encoded strings when using find with ActiveRecord objects
Examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# synchronize example post = BlogPost.find_by_author_name( 'zdennis' ) columns = [ :author_name, :title ] values = [ [ 'yoda', 'test post' ] ] BlogPost.import columns, values, :synchronize=>[ post ] post.author_name # => 'yoda' # using synchronize option with import posts = BlogPost.find(:all) BlogPost.import( columns, values, :synchronize=>posts) # using arrays with the _contains suffix BlogPost.find( :all, :conditions=>{ :author_name_contains=>[ 'ab', 'oc', 'ed' ] } ) |
Questions, Comments
zach dot dennis at gmail dot com
Introducing acts_as_comparable
on April 21, 2007 @ 01:52 AM
Mark VanHolstyn and Zach Dennis kick out another ActiveRecord plugin. The previous plugin ActiveRecord::Extensions now has a smaller, helpful cousin. This plugin has been in use for over a year but not released until tonight!
“acts_as_comparable” is plugin for ActiveRecord which allows you to easily compare and determine the differences between two ActiveRecord models.
1 2 3 4 5 6 7 8 9 10 11 |
class Person acts_as_comparable :only=>[:first_name, :last_name] end joe = Person.new :first_name=>"Joe", :last_name=>"Smith" joseph = Person.new :first_name => "Joseph", :last_name=>"Smith" joe.same?( joseph ) # => false joe.different?( joseph ) # => true joe.differences( joseph ) # => {:first_name=>["Joe", "Joseph"]} |
The usage in the above example shows the only option, but this also works with no options, the except option and also the attrs_map option. See it’s ruby doc for more information.
Installing as a RubyGem
gem install -r acts_as_comparable |
Installing as a Plugin
Installing from a version
script/plugin install http://rails.lotswholetime.com/svn/acts_as_comparable/tags/acts_as_comparable-1.1 |
Refactoring ActiveRecord::Base
on March 15, 2007 @ 03:02 AM
ActiveRecord (AR) is one of my favorite programming libraries ever created. I am very thankful that DHH woke up one day and decided to author it.
Recently there has been talk in a few threads (How I Monkey Patched AR and ActiveRecord Refactoring) on the Rails-Core list which are trying to invite AR contributors, plugin authors and all around AR enthusiasts to think about refactoring AR.
The Good
AR is the best ORM that I know of and actively use. ActiveRecord::Base is the centralized theme of ActiveRecord. It’s what you subclass when you need to model an actual database table. It’s where you declare your associations (has_one, belongs_to, etc…). It connects your application code to your database storage.
The Bad
ActiveRecord::Base dishes off some of the SQL generation tasks to the underlying connection adapter. This means that if you’re using MySQL then the MysqlAdapter is going to be responsible for quoting valute (for instance the methods quote and quote_value).
Unfortunately ActiveRecord::Base remains to keep some functionality it should most likely give up to the connection adapters. This functionality includes any partial SQL that you see in ActiveRecord::Base, in my opinion.
The Ugly
Since ActiveRecord::Base is holding onto some implementation it doesn’t deserve you can’t get a clean interface for extending aspects of SQL generation without overriding and reimplementing methods on ActiveRecord::Base.
The downside to this is that it’s not isolated to even just your adapter. Even more so, it’s not isolated to just your functionality. Why is this bad? It increases the risk that a bug in your code is going to bring down other parts of the system which may or may not be totally unrelated.
Examples of this include how queries are built. The attribute_conditions method on ActiveRecord::Base is responsible for handling Array, Range and nil objects specifically. If your object isn’t one of those then you’re going to get stuck with an equals = comparison. An example of this is when you do a :find method call with conditions Hash. For example:
SomeModel.find :all, :conditions=>{ :id => [ 1, 2, 3 ], :age=>(20..25) } |
The above code is great, but what happens when you want to use database specific features (or features which use different SQL dialect) like one regular expression searching, database functions, subqueries. Or even supporting additional query modifier statements like the WITH clause that MS SQL, Oracle, DB2 and PostgreSQL8.2 offer, or even the infamous ON DUPLICATE KEY UPDATE functionality that MySQL offers?
Plugins – An Existing Solution
One solution is to have everyone release plugins which extend, implement, override or re-implement functionality that AR currently offers. Some folks in the Rails community even like to suggest that people create plugins and then if the plugin becomes popular they’ll consider putting it into core.
While I see the benefit in this (if no one uses the functionality why does it belong into core?) I also see the need to start considering and refactoring AR to support what some would consider cleaner, more extendable code.
I have even gone as far as implementing ActiveRecord::Extensions which is a plugin that is trying to solve a lot of these issues. And I believe it has in some regards.
Why Plugins and Method Overriding Isn’t The Final Answer
Plugins and method overriding (for all of those calls to alias, you know who you are) aren’t the solution for where AR probably should go as Rails starts on its sweep of moving to a 2.0 release.
The problem is that when several plugins have to forcefully override core methods on ActiveRecord::Base to extend the functionality it screams out to me that ActiveRecord could use a little refactoring love. This would allow alot less method overriding and aliasing while still allowing plugin developers to extend AR’s functionality.
Fowler talks about code smells and the continuous overriding of core methods seems to indicate one or possibly more.
How Can AR Separate Subjective Desires From Objective Needs
A few simple guidelines to use:
- Domain specific problems shouldn’t be put into ActiveRecord core.
- Generic database solutions should be put into ActiveRecord core.
- A public interface should be put onto ActiveRecord::Base if it operates on a given table or model objects
- Implementation details should be hidden inside of an adapter somewhere. (ie: no SQL generation in ActiveRecord::Base)
- Generic solutions which impose different SQL dialect should be put into adapters or another component which adapters know how to use.
A few simple questions to think when deciding to extend AR with a plugin or introduce new ideas to AR core:
- Is the functionality provided by more then one database even if the how its done differs?
- Can this functionality be isolated or encapsulated in a way that reduces the risk of breaking other AR functionality should a bug be found? (ie: are you overriding core ActiveRecord::Base methods and aliasing the original? If so this is a very easy bug to introduce here.)
- Does this functionality make sense in only your problem domain, or does it makes sense in most or all problem domains?
Moving Forward
I am working on a patch to AR core which removes all SQL code in ActiveRecord::Base and extracts it out into the connections adapters. It will provide an API for creating additional or specific query based modifiers. This will provide things like prefix and suffix modifiers. It will also separate generic query generation (SQL dialect that all databases support) from non-generic query generation.
This functionality already exists in ActiveRecord::Extensions and you can see its usage examples in Ruby Insiders December Article . The implementation will slightly differ since by patching AR core itself I’ll be able to introduce simpler code.
The ability to create and extend custom better finder support will be introduced in this patch which allow core developers and/or plugin developers to isolate their code changes and to include that support into the adapters of their choice, without overriding AR core methods.
Thoughts?
If you’ve read this whole post then you’re most likely interested in AR and it’s future. What do you think?
ActiveRecord::Extensions 0.5.2 Released!
on March 15, 2007 @ 01:32 AM
ActiveRecord::Extensions 0.5.2 is released! A rubygem has been born!
Installation is so easy now for ActiveRecord::Extensions:
gem install -r 'ar-extensions' |
Enjoy!
0.5.1 was also released, but I quickly released 0.5.2 after it to fix a possible bug with method aliasing. This would only occur if you had another plugin or rubygem which used the same alias name for ActiveRecord::Base#quote
ActiveRecord::Extensions 0.5.0 Released!
on March 14, 2007 @ 02:14 AM
ActiveRecord::Extensions 0.5.0 is released! This release includes support for querying against Time objects against ActiveRecord columns which are considered :datetime by ActiveRecord’s standards .
Code Example
To find all blog posts within the last week:
BlogPost.find( :all, :conditions=>{ :created_at_gt => Time.now-1.week } ) |
To find all posts within the last year:
BlogPost.find( :all, :conditions=>{ :created_at_gt => Time.now-1.year } ) |
To find all posts over a year old:
BlogPost.find( :all, :conditions=>{ :created_at_lt => Time.now-1.year} ) |
User.find( :all, :conditions=>{ :logged_in_at_gt => Time.now-15.minutes} ) |
Supported Suffix Modifiers
This particular query addition supports the following column name suffix modifiers (ie: the “_lt” in the “created_at_lt”).- _lt => less than
- _gt => greater than
- _lte => less than or equal to
- _gte => greater than or equal to
- _ne => not equal to
- _not => not equal to
- eq => equal to _(this is implied without a suffix present)
MySQL TIMESTAMP Disclaimer
This does not work on TIMESTAMP columns for MySQL due to an issue with the inconsistency of TIMESTAMP columns in varying versions of MySQL and due to the nature of server configurations which can alter the behavior of TIMESTAMP columns.
PostgreSQL Support Note
I recently switched to a Mac, I am compiling PostgreSQL 8.1 and 8.2 as I type this. As soon as I can test this functionality against PostgreSQL I will release an update with that support.
Download It Now!
- Rubyforge: http://rubyforge.org/frs/?group_id=2113
ActiveRecord::Extensions 0.4.0 Released!
on February 12, 2007 @ 02:22 AM
ActiveRecord::Extensions 0.4.0 is released!
Updates
- added to_csv functionality (works with belongs_to, has_one and has_many relationships)
- added temporary table functionality
- added foreign key functionality
to_csv functionality
Example 1, exporting all fields
1 2 3 4 |
class Book < ActiveRecord::Base ; end book = Book.find( 1 ) book.to_csv |
Example 2, only exporting certain fields
1 2 3 4 |
class Book < ActiveRecord::Base ; end book = Book.find( 1 ) book.to_csv( :only=>%W( title isbn ) |
Example 3, exporting a model including a belongs_to association
1 2 3 4 5 6 |
class Book < ActiveRecord::Base belongs_to :author end book = Book.find( 1 ) book.to_csv( :include=>:author ) |
This also works for a has_one relationship. The :include option can also be an array of has_one/belongs_to associations. This by default includes all fields on the belongs_to association.
Example 4, exporting a model including a has_many association
1 2 3 4 5 6 |
class Book < ActiveRecord::Base has_many :tags end book = Book.find( 1 ) book.to_csv( :include=>:tags ) |
This by default includes all fields on the has_many assocaition. This can also be an array of multiple has_many relationships. The array can be mixed with has_one/belongs_to associations array as well. IE: :include=>[ :author, :sales ]
Example 5, nesting associations
1 2 3 4 5 6 7 8 9 |
class Book < ActiveRecord::Base belongs_to :author has_many :tags end book = Book.find( 1 ) book.to_csv( :include=>{ :author => { :only=>%W( name ) }, :tags => { :only=>%W( tagname ) } ) |
Example 6, using Arrays returned by find
1 2 3 4 5 6 7 8 9 |
class Book < ActiveRecord::Base belongs_to :author has_many :tags end books = Book.find( :all ) books.to_csv( :include=>{ :author => { :only=>%W( name ) }, :tags => { :only=>%W( tagname ) } ) |
Temporary Table Support
Example 1, using defaults
1 2 3 |
class Project < ActiveRecord::Base ; end Project.create_temporary_table |
This creates a temporary table named ‘temp_projects’ and creates a constant name TempProject. The table structure is copied from the projects table.
Example 2, using :table_name and :model options
Project.create_temporary_table :table_name=>'my_projects', :model=>'MyProject' |
This creates a temporary table named ‘my_projects’ and creates a constant named MyProject. The table structure is copied from the projects table.
Example 3, using :like
ActiveRecord::Base.create_temporary_table :like=>Project |
This is the same as calling Project.create_temporary_table.
Example 4, using block form
1 2 3 |
Project.create_temporary_table do |t| # ... end |
Using the block form will automatically drop the temporary table when the block exits. t which is passed into the block is the temporary table class. In the above example t equals TempProject. The block form can be used with all of the available options.
Foreign Key Support
Enables support for enabling and disabling foreign keys for the underlying database connection for ActiveRecord. This can be used with or without block form. This also uses the connection attached to the model.
Example 1, without block form
1 2 |
Project.foreign_keys.disable Project.foreign_keys.enable |
If you use this form you have to manually re-enable the foreign keys.
Example 2, with block form
1 2 3 4 5 6 7 |
Project.foreign_keys.disable do # ... end Project.foreign_keys.enable do # ... end |
If you use the block form the foreign keys are automatically enabled or disabled when the block exits. This currently does not restore the state of foreign keys to the state before the block was entered.
Download It Now!
ActiveRecord::Extensions 0.4.0
Check it out from SVN into your Rails project
svn co svn://rubyforge.org/var/svn/arext/tags/ar-extensions-0.4.0 vendor/plugins/
Temporary Table Nicety
on January 31, 2007 @ 05:53 AM
A taste of temporary table support for ActiveRecord and MySQL.
Creating Temporary Tables
Temporary tables can be created by using two forms. Temporary tables will generate the following SQL:
CREATE TEMPORARY TABLE table_name LIKE base_table |
The First Form
A block form which manages your temporary table (ie: it creates the table at the start of the block and ensures it is removed by the end of the block, similar to how IO objects work in ruby) .
The Second Form
The second form allows you to assign your temporary table to a variable. You are responsible for destroying it. Or you could just leave it around until your ruby process is done and your database will kill it when the connection closes.
Here’s an example using the block form:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# create our model class Account < ActiveRecord::Base end # perform the update Account.create_temporary_table do |t| t.new.is_a? ActiveRecord::Base # => true t.new.is_a? ActiveRecord::TemporaryTable # => true # You can treat 't' like any model class, and create new records, # add validations, etc. record = t.new :name=>"New Account" record.save record.create :name => "Another new account" # TempAccount is created to reference this model class as well TempAccount == t # => true # the "end" block here will drop our temporary table and remove # our TempAccount constant end |
Checking It Out
You can pull it down from trunk right now. It will be included in the next release (which will be 0.4.0):- svn checkout svn://rubyforge.org/var/svn/arext/trunk/ar-extensions
Like Tables
Like tables are similar to temporary tables. In fact they are created in the exact same way except that they are permanent. They are normal tables until you destroy them. A like table simply generates the following sql:
CREATE TABLE table_name LIKE base_table |
You can create this the same way way you create temporary tables, just pass in the :permanent option as a parameter:
1 2 3 4 5 6 7 8 9 10 |
class Account < ActiveRecord::Base end # t is your model class, also aliased as TempAccount. temp_account_model_class = Account.create_temporary_table :permanent=>true TempAccount == temp_account_model_class # => true # drop your table TempAccount.drop |
to_csv update (nearing Round #2)
on January 04, 2007 @ 07:17 AM
Round #2 of the to_csv functionality is nearing completion. The updates so far are:
- supports associations via the :include option on a per model object basis
- supports custom headers through the model class
It will work on an ActiveRecord model object itself or an array of ActiveRecord model objects that are returned from any “find” method call.
Basic :include option
The :include option will bring in an association that is created with belongs_to or has_many declarations.
Here is a basic example for a belongs_to association to be included in the CSV results with default options:
csv = People.find( :all ).to_csv( :include=> [ :address ] ) |
- :headers=>true
- :headers=>false
Updated :headers Option
To detour from the :include options for a moment, the :headers option has been updated to accept:- an array of column names as Symbols or Strings
- a Hash of column name to header name mappings as Symbols or Strings
Here are a few examples of the new headers option in use:
1 2 3 4 5 6 7 8 |
# using symbols csv = People.find( :all ).to_csv( :headers => [ :first_name, :last_name ] } # using strings csv = People.find( :all ).to_csv( :headers => [ 'first_name', 'last_name' ] } # using a Hash to supply custom headers csv = People.find( :all ).to_csv( :headers => { :first_name=>'FirstName', :last_name=>'LastName' } |
Since Arrays are ordered the CSV columns will be in the order of the Array. Since Hashes aren’t ordered the order of the columns will be done alphabetically based on the field name.
Intermediate Usage Of :include
The :include option can take:- an Array of Strings or Symbols denoting the name of the association
- a Hash of Hashes mapping the association name to an options Hash
The options Hash is what you’re already passing into the to_csv method. If you use the Hash form of :include you get the ability to embed different options per each association included.
Here are some more intermediate examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
people = People.find( :all ) # Using a Hash to specify the column you want from the Address relationship people.to_csv( :include=>{ :address=>{ :only=>[ :street, :city, :state, :zip ] } } ) # Using a top level options to include only certain fields from each person and # then options to include certain fields from each person's address. people.to_csv( :only=>[ :first_name, :last_name ], :include=>{ :address=>{ :only=>[ :street, :city, :state, :zip ] } } ) # Modification of the last example to use custom headers people.to_csv( :headers=>{ :first_name=>"FName", :last_name=>"LName" } , :include=>{ :address=>{ :headers=>{ :city=>"Hometown", :state=>"ST" } } } ) |
That’s a brief summary for where the state of affairs is at for now. If you want more information please read all of the nice tests by checking out the SVN repository.
There are some other usages that you will be able to do like (see below) but the tests and functionality has not been intentionally implemented although it may/may work off from existing functionality:- support multiple :include options for multiple associations
- embed :include options inside of :include options for chaining associations
One thing I don’t like about all of this so far is all of the curly braces, brackets and potentially parenthesizes. The more :includes you want to have, the more curly braces you’re going to have most likely.
I’m trying to think of a block like declarative syntax to handle this, but I haven’t come up with any worthwhile yet. If you’ve got any ideas I’m all ears.
Upcoming 0.4.0 release
This will be launched in a 0.4.0 release which should be soon. I’ve got to be out of town part of this weekend, and the most of next week so I am going to see if I can crunch it in before the next Monday.
ActiveRecord::Extensions 0.3.0 Released!
on December 30, 2006 @ 12:50 AM
ActiveRecord::Extensions 0.3.0 is released! Download it here.
There are no functionality changes in this release. There are two changes:- thanks to Michael Schuerig for pointing out a potential namespace issue which is fixed in this release
- tests are now loaded in the a new ruby process rather then into the same ruby process as rake tasks when running rake test:
ActiveRecord::Extensions 0.2.0 Released!
on December 22, 2006 @ 07:50 AM
ActiveRecord::Extensions 0.2.0 is released! Download it here .
Updates include:- Changes to the to_csv method to support an API compatible with the ToCSV plugin by Chris Abad
- Added support for SQLite and SQLite3
- Added “does_not_match” suffix for :conditions which want to negate a regex
- Added “not_between” suffix for :conditions which want to negate a range
- Converted test database schema to use migrations, and added tasks to load test database
to_csv updates
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Developer < ActiveRecord::Base ; end developers = Developer.find( :all ) # Output default headers, this is implicit if headers is not provided csv = developers.to_csv( :headers => true ) # Output no headers csv = developers.to_csv( :headers => false ) # Output only the following columns csv = developers.to_csv( :only=>[ :id, :name ] ) # Output all columns except the following csv = developers.to_csv( :except => [ :id, :name ] ) |
Updates to better finders
I was typing some code today and I was using Ranges and Regexps. It just felt write to say that something_does_not_match when matching between a Regular Expression. And then I decided to add “not_between” for Ranges.
1 2 3 4 5 6 7 |
class Developer < ActiveRecord::Base ; end # find all developers whose name does not match the regex Developer.find :all, :conditions => { :name_does_not_match => '^Zach' } # find all developers whose IQ is not between 80 and 120 Developer.find :all, :conditions => { :iq_not_between => ( 80 .. 120 ) } |
Running ActiveRecord::Extensions Tests
ActiveRecord::Extensions provides a great testing suite. Just run “rake -T” to see all of the supported tasks. In 0.2.0 the ability to load a test database from migrations has been added.
# Usage
rake db:test:prepare_<db>
# IE:
rake db:test:prepare_mysql
# Then run your tests:
rake test:mysql
# And don't forget to test against activerecord
rake test:activerecord:mysql ~/rails_trunk/activerecord
The only prerequisite of the above is to make sure that your connection is specified correctly for the database you want to test. To do this go into the tests/connections/native_
Enjoy 0.2.0!
For any questions or comments let me know.- zach DOT dennis AT gmail DOT com
ActiveRecord::Extensions SQLite Compatibility
on December 21, 2006 @ 03:18 AM
The upcoming 0.2.0 release is going to include SQLite compatibility, and it looks like that is going to be released before the weekend hits! Any one out there who uses SQLite and wants to leverage the usefulness of ActiveRecord::Extensions, wait no longer (then 1 to 2 more days)!
The upcoming 0.2.0 release will update the to_csv and to_csv_file method arguments.
1 2 3 4 5 6 7 8 9 10 11 |
# rather then array_of_models.to_csv( :headers => [ :field1, :field2, :field3 ] ) # it'll be array_of_models.to_csv( :headers => true|false, :only=> [ :field1, :field2, :field3 ] ) # or array_of_models.to_csv( :headers => true|false, :except=> [ :id ] ) # and the same goes for the options that were passed into to_csv_file as well array_of_models.to_csv_file( filename, :headers=>[ :name, :salary ] ) |
Thanks to Dan Kubb for bringing this up. The API is borrowed from Chris Abad’s ToCSV plugin.
After that I’ll be on holiday vacation and I hope to kick out some cool stuff, like the :include option that Dan Kubb mentioned. for the to_csv.
ActiveRecord::Extensions 0.1.0 Released!
on December 17, 2006 @ 01:51 AM
ActiveRecord::Extensions 0.1.0 is released and it’s getting some press! An article has been published on Ruby Inside’s Advent Calendar . Thanks to Peter Cooper for publishing the article.
Release Notes
ActiveRecord::Extensions 0.1.0 features:
- to_csv functionality for Arrays returned by ActiveRecord::Base.find methods
- to_csv_file functionality for Arrays returned by ActiveRecord::Base.find methods
- Custom query object support for ActiveRecord::Base.find
- Official better finder support for MySQL and PostgreSQL
- Generic better finder support for all other database adapter supported by ActiveRecord
- Official import functionality support for MySQL and PostgreSQL
- Generic import functionality support for all other database adapters supported by ActiveRecord
0.1.0 is actually the seventh release of ActiveRecord::Extensions, it’s version number is so low because as more adapters are officially supported, it will quickly rise towards a 1.0.0 release.
Official Support vs. Generic Support
Official support means that I have tests for the adapter in question, and it without a doubt works with ActiveRecord::Extensions.
Generic support means that I have implemented default ActiveRecord compatibility with all of the features. It should work with all supported adapters of ActiveRecord, but there are not tests in my library testing those adapters.
to_csv
to_csv has been added as a method to all Arrays returned by ActiveRecord::Base.find. You can now quickly and painlessly turn ActiveRecord objects into CSV format. This functionality does rely on faster_csv (1.0.0 or higher) being installed:
1 2 3 4 |
class Project < ActiveRecord::Base ; end projects = Project.find( :all ) csv = projects.to_csv |
You can also pass in an array of headers that you want as Strings or Symbols:
csv = projects.to_csv( :headers => [ :project_name, :started_on, :estimated_due_date ] ) |
to_csv_file
to_csv_file has been added as a method to all Arrays returned by ActiveRecord::Base.find. It gives you the ability to quickly csv files, much like it’s sibling function to_csv. Instead of simply returning a CSV string it writes a file to disk:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
projects = Project.find( :all ) # Writes projects.csv to disk using the 'w' file mode operation projects.to_csv_file( 'projects.csv' ) # Writes projects.csv to disk using the 'a' (append) file mode operation. # Any IO mode is supported as the second parameter. projects.to_csv_file( 'projects.csv', 'a' ) # Writes projects.csv to disk specifying what columns headers to use: projects.to_csv_file( 'projects.csv', :headers=> [ :project_name, :started_on, :estimated_due_date ] ) |
Refactorings
This release also includes some refactorings of how ActiveRecord::Extensions internals work to support better extensibility down the road.
Download and Install
Download it now from rubyforge! .
Installation is simple. You can put it in your Rails application by placing the extracted directory in your RAILS_ROOT/vendor/plugins directory or you can put it in any application and require the init.rb file included in the ar-extensions-0.1.0./ directory.
Upcoming in the next release will be easier installation via “gem install” or installation as a Rails plugin from your rails application using “script/plugin”.
Contact the Developer
Any questions, comments or bugs please feel free to use the Project Tracking features on the RubyForge project site
- Email: Zach Dennis – zach DOT dennis AT gmail DOT com

