activerecord 2.3.2
activerecord: ^2.3.2 copied to clipboard
An Active Record implementation for the Dart language
ActiveRecord #
Implementation of the Active Record pattern with some specialties from the Dart language.
How to use #
Preparation #
In order to use ActiveRecord, you have to subclass the Collection class.
Variables of the Collection are defined by overriding the get variables method.
You can override this method in a variety of styles: For instance, if you simply want
to define a String variable (like e.g. name), the result of get variables should
be `["name"]. If you want to specify type of the variable as well as constraints or
validations, you've got two options: You can either hand over a list, with
the name as first, the type as second, constraints and validations as fourth and fifth
argument, or hand over a Variable object.
Example of List approach:
get variables => [["name", "Integer"]];
Currently supported types are String, Integer, Double, Bool, Text and Datetime.
Another important point is overriding the get adapter method. If you don't
override this method, the collection will use the defaultAdapter as adapter,
which is by default null. If the defaultAdapter is null and it is the first time
the defaultAdapter is looked up, ActiveRecord will search the directory from where
you ran the current script for a database.yaml file and use the adapter with
the specified environment (default: development, you can change this by setting
the top level environment variable in ActiveRecord). If it can't find a
database.yaml file there, it will also lookup the parent directory for
that file. If it still can't find a file there, it will set the defaultAdapter
to null. An example of a specification of a postgres adapter can be found in
test/database.yaml. Adapters are available
via the ActiveMigration library,
which also features generation and execution of Migration files. Contribution
of further adapters as well as contribution to this repository are appreciated.
Creating, saving, finding and destroying Records #
Creating
Creation of Collection instances can be done via the get nu method of the
Collection class. This immediatly returns a Model instance. You can then
Manipulate this Model until you want to save it.
Saving
To save it, call the save method on the Model instance. This returns a
future containing the saved Model.
Finding
For finding, there are four methods of each Collection instance:
find(int id)
This returns a Future containing the Model with the specified id. Only a single Model instance is returned.
all({int limit, int offset})
Returns all Models of the Collection. You may specify limit and/or offset, if you don't want all or just models after a specific number of models.
where(String sql, List params, {int limit, int offset})
This executes the given sql command on the underlying adapter (doesn't have to be sql, but in the initial versithreeon this was the name). Be sure to put the search parameters into the params List because then the adapter can do prepared statements.
findByVariable(Map<String, dynamic> input, {int limit, int offset})
This is the adapter independent way of finding variables. Simply specify a map of variable names and the corresponding values, which will then be returned.
Destroying
Destroying is very simple: Get a Model which has been persisted via the
various find methods and call the destroy method on it. This returns
a Future with a boolean indicating the success of the destroy operation.
Consistency of the persistence #
In order to provide a consistent persistence, there are two ways of providing checks to the given variables: Validations and Constraints. Constraints are checks which run on the adapters, Validations are checks which run inside ActiveRecord. This results in Validations being always available and Constraints being available only on some Adapters.
Further subclassing of Collections #
Model methods
Methods, which are available on Model instances can be specified inside the collection. A Model method has a Model as the first parameter. So, a Model method could look like this:
void say(Model m, String text) {
print(m["name"] + " wants to say $text");
}
Relations
Relations can be specified by overriding the appropriate methods. Those methods are:
- hasMany
- belongsTo
Relations can be specified in two ways: One way is to directly specify the type of the other collection and the other way is to specify a Relation object.
Example:
List get belongsTo => [AnotherCollection];
To get related Models of a Model instance, simply call a method with
the lowercase name of the related collection. If it is a "hasMany" relation,
add an "s". Also, if it is a "hasMany" relation, you can create Model instances
of the related Collection by calling nu on the result of this method.
Example:
// Receiving models
mymodel.anothercollections.get.then((anotherCollectionModels) => ...);
// Creating models
var newRelatedModel = mymodel.anothercollections.nu;
Lifecycle management #
Some methods on models should be triggered in specific states of the Lifecycle of a Model. For this, there are Lifecycle methods. Current Lifecycle methods are:
- beforeCreate(Model m)
- afterCreate(Model m)
- beforeUpdate(Model m)
- afterUpdate(Model m)
- beforeDestroy(Model m)
- afterDestroy(Model m)
