Objectify
Inspired by Active Record, Objectify is a Ruby object-relational mapping (ORM) library, which uses SQLite3 as its database. Objectify provides an SQLObject base class. When users define a new class (model) that is a subclass of SQLObject, a mapping between the model and an existing table in the database is established. Moreover, models can connect with other models by defining associations.
Demo
For demo purposes, a database geo.db is provided. To experience Objectify, run the following commands in your terminal:
git clone https://github.com/davidfeng88/Objectify.gitcd Objectify/irbload 'geo.rb'- Try the following commands!
# all
City.all
# => [#<City:0x00007fa4fd09f5c0 @attributes={:id=>1, :name=>"Beijing", :country_id=>1}>, ...]
# find
Country.find(3)
# => #<Country:0x00007fa4fc1bca58 @attributes={:id=>3, :name=>"United States", :continent_id=>2}>
# first, last, associations
beijing = City.first
# => #<City:0x00007fa4fc2e6af0 @attributes={:id=>1, :name=>"Beijing", :country_id=>1}>
beijing.country
# => #<Country:0x00007fa4fd14f4c0 @attributes={:id=>1, :name=>"China", :continent_id=>1}>
beijing.continent
# => #<Continent:0x00007fa4fd14c068 @attributes={:id=>1, :name=>"Asia"}>
canada = Country.last
# => #<Country:0x00007fa4fc19c118 @attributes={:id=>4, :name=>"Canada", :continent_id=>2}>
canada.continent
# => #<Continent:0x00007fa4fd15cd50 @attributes={:id=>2, :name=>"North America"}>
# where
japan = Country.where(name: "Japan").first
# => #<Country:0x00007fa4fc122660 @attributes={:id=>2, :name=>"Japan", :continent_id=>1}>
kyoto = City.new(name: "kyoto", country_id: japan.id)
# => #<City:0x00007fa4fc2e4188 @attributes={:name=>"kyoto", :country_id=>2}>
kyoto.save
# => 8
City.last
# => #<City:0x00007fa4fd13f930 @attributes={:id=>8, :name=>"kyoto", :country_id=>2}>
kyoto.name = "Kyoto"
# => "Kyoto"
kyoto.save
# => []
City.last
# name updated!
# => #<City:0x00007fa4fd12ec20 @attributes={:id=>8, :name=>"Kyoto", :country_id=>2}>Note: Check out geo.sql file for the content of the demo database.
Common Methods
-
::allreturns an array of all instances of the class. -
::firstand::lastreturn first and last instance of the class respectively. -
::find(id)returns the instance with the id provided. It returnsnilif not found. -
::new(params)creates a new instance with an optional hash of parameters. -
#savesaves the changes of the instance in the database. It calls#insertor#updatebased on whether the id isnilor not.
Other methods
-
::columnsreturns an array of column names (symbols). -
::table_nameand::table_name=: table name getter and setter methods.
Search
::where(params)takes in a hash of parameters. It returns an empty array if nothing is found. For example:
Country.where(name: "Japan") # => an array of Country instances where the name is "Japan"Association
- Associations are defined in the
.rbfile before::finalize!. For example:
class Continent < SQLObject
has_many :countries
finalize!
end
class Country < SQLObject
belongs_to :continent
finalize!
end-
Supported associations currently include
has_many,belongs_to,has_one_through. -
has_manyandbelongs_totakes a required name and an optional hash forclass_name,primary_key, andforeign_key. -
has_one_throughrequires three arguments:name,through_name,source_name.has_one_throughconnects twobelongs_toassociations. For example, in the demo database:Cityhas abelongs_toassociation (:country) withCountryCountryhas abelongs_toassociation (:continent) withContinent- I defined a
has_one_throughassociation (:continent) forCityusing the following options:name::continentthrough_name::countrysource_name::continent
Use Objectify with your own database
You need to create three files (.sql, .db, and .rb) as follows. Refer to geo.sql and geo.rb files if needed.
- Write a SQL source file (
.sql). - Run
cat FILENAME.sql | sqlite3 FILENAME.dbto generates the database file (.db). - Edit the
SQL_FILEandDB_FILEconstants in/lib/db_connection.rbso that they point to the.sqland.dbfiles in step 1 and 2. - Write a Ruby file (
.rb) to define the models and set up the associations. - In
irborpry, load the.rbfile and you are good to go!
Future Work
- Write
whereso that it is lazy and stackable. Implement aRelationclass. - Validation methods/validator class.
has_many :through- This should handle both
belongs_to => has_manyandhas_many => belongs_to.
- This should handle both
- Write an
includesmethod that does pre-fetching. joins

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
