A brief presentation describing Tenacity, a ruby gem that provides a database client independent way of managing relationships between models backed by different databases.
3. class Car
include MongoMapper::Document
def wheels
Wheel.where(:car_id => self.id)
end
end
class Wheel < ActiveRecord::Base
# car_id defined on the table
def car
Car.find(self.car_id)
end
end
4. Problems
• Lots of boilerplate code
• Bogus values can be stored in car_id
• What happens if the Car is deleted?
• Objects fetched from the database each time
• Adding new wheels is awkward
5. Introducing Tenacity
• Heavily based on ActiveRecord::Associations
• Support for has one, belongs to, and has many
relationships
• Adds foreign key like behavior
• Can “clean up” when objects are deleted
• Related objects are fetched from the database
once and then cached
6. Introducing Tenacity
• Easily work with collections of associated
objects
• Polymorphic associations
• Read only associations
• Support for a wide array of popular Ruby
ORM/ODM libraries
7. class Car
include MongoMapper::Document
def wheels
Wheel.where(:car_id => self.id)
end
end
class Wheel < ActiveRecord::Base
# car_id defined on the table
def car
Car.find(self.car_id)
end
end
8. class Car
include MongoMapper::Document
include Tenacity
t_has_many :wheels
end
class Wheel < ActiveRecord::Base
include Tenacity
t_belongs_to :car
end
9. class Car
include MongoMapper::Document
include Tenacity
t_has_many :wheels
t_has_one :dashboard
end
class Wheel < ActiveRecord::Base
include Tenacity
t_belongs_to :car
end
class Dashboard < CouchRest::Model::Base
include Tenacity
use_database MY_DATABASE
t_belongs_to :car
end
10. car = Car.create
# Set the related object
dashboard = Dashboard.create
car.dashboard = dashboard
car.save
# Fetch related object from the respective database
car.dashboard
# Fetch related object id
car.dashboard.car_id
11. # Set related objects
wheel_1 = Wheel.create
wheel_2 = Wheel.create
wheel_3 = Wheel.create
wheels = [wheel_1, wheel_2, wheel_3]
car.wheels = wheels
car.save
wheel_1.car_id # car.id
# Fetch array of related objects from the respective database
car.wheels # [wheel_1, wheel_2, wheel_3]
# Fetch ids of related objects from the database
car.wheel_ids # [wheel_1.id, wheel_2.id, wheel_3.id]
# Add a related object to the collection
new_wheel = Wheel.create
car.wheels << new_wheel
car.save
car.wheels # [wheel_1, wheel_2, wheel_3, new_wheel]
12. How Does It Work?
• Extends supported libraries with a common set of
methods
• Tenacity uses these methods to work with the
objects in a generic fashion
• Methods are added to the model class to interact
with the relationship
• ORM/ODM callback functionality is used to trigger
Tenacity to save associated objects, cleanup
associations, etc
14. What’s On Deck?
• Add support for many to many associations
• Add support for build and create methods
• Author.posts.build
• Improve performance
• Continue adding support for additional ORM/
ODM libraries