DataMapped
Ruby mixins for DataMapper. Don't repeat yourself, control your join tables, prevent your resources from being deleted, and full-text search across your resources.
Installation
Add this line to your application's Gemfile:
gem 'data_mapped'
And then execute:
$ bundle
Or install it yourself as:
$ gem install data_mapped
Usage
Normal Model
This mixin sets up your class for DataMapper, and adds @id
, @created_at
,
and @updated_at
properties that behave as expected.
Rationale: Don't repeat yourself. Don't manually add the same standard properties to each of your models.
require 'data_mapped/model'
class Movie
include DataMapped::Model
property :title, String, required: true
property :description, Text
end
Join Model (for a Join Table)
This mixin sets up your class for DataMapper, and adds @created_at
and
@updated_at
properties that behave as expected. This join model differs
from the normal model in that the join model doesn't add an
@id
property, as it expects for your class to define a composite primary key
using #belongs_to
relationships.
Rationale: Tightly control your many-to-many associations. This is a helpful pattern to do something to a movie resource any time an actor is associated with it.
require 'data_mapped/join'
require 'data_mapped/model'
class Movie
include DataMapped::Model
property :title, String, required: true
property :description, Text
has n, :actors, through: Resource
end
class Actor
include DataMapped::Model
property :name, String, required: true
has n, :movies, through: Resource
end
class ActorMovie
include DataMapped::Join
belongs_to :actor, key: true
belongs_to :movie, key: true
end
Integration note: Your join model class name must be a Pascal case, alphabetized concatenation of the names of the two models that you're joining. Internally, DataMapper introspects your join model class name and uses it to determine the name of the join table in your database.
Permanent Model (that Can't be Destroyed)
This mixin prevents resources of your class from being destroyed (at least in
the typical fashion using
#destroy
).
It's meant to be used in conjunction with either the
normal model or the
join model mixin.
Rationale: Prevent accidentally deleting resources that shouldn't be
deleted, if you have itchy fingers and play around too much in irb
on
production like I do. Our use case is that movies should be created, read,
and updated, but never deleted.
require 'data_mapped/model'
require 'data_mapped/permanent'
class Movie
include DataMapped::Model
include DataMapped::Permanent
property :title, String, required: true
property :description, Text
end
Integration note: You can still delete permanent models with
#destroy!
.
In general, make a practice out of staying away from DataMapper's unsafe bang
(!) methods. These
bang methods don't run validators or callbacks.
:-(
Searchable Model
This mixin duct tapes your class together with Sunspot and Solr, and makes your class's resources indexed and searchable. It's meant to be used in conjunction with the normal model mixin.
Rationale: Everyone loves full-text search, and this makes it easy to get DataMapper to talk to Sunspot. Include this mixin, define your model, then use Sunspot's powerful DSL to define what should be indexed and how it should be weighted.
require 'data_mapped/model'
require 'data_mapped/searchable'
class Movie
include DataMapped::Model
include DataMapped::Searchable
property :title, String, required: true
property :description, Text
has n, :actors, through: Resource
searchable auto_index: true, auto_remove: true do
text :title, boost: 2.0
text :description
text :actor_names, boost: 1.5 do
self.actors.map(&:name).join(', ')
end
end
end
class Actor
include DataMapped::Model
property :name, String, required: true
has n, :movies, through: Resource
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request