Orator 0.7 is now out. This version introduces relationship decorators, seeding, model factories and cache support. It also brings various performance improvements and fixes, especially in the way relationships are handled.
For the full list of changes, see the CHANGELOG
Relationship decorators
The way model relationships are declared has been largely modified and improved.
Now, relationships are declared via decorators.
Even though decorators are the preferred way the old notation is still supported.
Here is an example:
Model Factories
When testing, it is common to need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Orator allows you to define a default set of attributes for each of your models using "factories":
Within the function (here users_factory
), which serves as the factory definition,
you can return the default test values of all attributes on the model.
The function will receive an instance of the Faker library,
which allows you to conveniently generate various kinds of random data for testing.
Multiple Factory Types
Sometimes you may wish to have multiple factories for the same model class.
For example, perhaps you would like to have a factory for "Administrator" users in addition to normal users.
You can define these factories using the define_as
method:
Instead of duplicating all of the attributes from your base user factory,
you can use the raw
method to retrieve the base attributes.
Once you have the attributes, simply supplement them with any additional values you require:
Using Factories In Tests
Once you have defined your factories, you can use them in your tests or database seed files
to generate model instances calling the Factory
instance.
So, let's take a look at a few examples of creating models.
First, we'll use the make
method, which creates models but does not save them to the database:
If you would like to override some of the default values of your models,
you can pass keyword arguments to the make
method.
Only the specified values will be replaced while the rest of the values remain
set to their default values as specified by the factory:
You can also create a Collection
of many models or create models of a given type:
Persisting Factory Models
The create
method not only creates the model instances,
but also saves them to the database using models' save
method:
Again, you can override attributes on the model by passing an array to the create
method:
Adding Relations To Models
You may even persist multiple models to the database.
In this example, we'll even attach a relation to the created models.
When using the create
method to create multiple models, a Collection
instance is returned,
allowing you to use any of the convenient functions provided by the collection, such as each
:
Seeding
Orator includes a simple method of seeding your database with test data using seed classes.
Seed classes may have any name you wish, but probably should follow some sensible convention,
such as UsersTableSeeder
, etc.
By default, a DatabaseSeeder
class is defined for you the first time you create a seed class.
From this class, you can use the call
method to run other seed classes,
allowing you to control the seeding order.
Writing Seeders
To generate a seeder, you may issue the seeders:make
command.
All seeders generated by the command will be placed in a seeders
directory
relative to where the command has been executed:
If you want the seed classes to be stored in another directory, use the ``-p/--path`` option
A seeder class only contains one method by default: run
.
This method is called when the db:seed
command is executed.
Within the run
method, you can insert data into your database however you wish.
You can use the QueryBuilder to manually insert data or you can use ModelFactories.
As an example, let's modify the UsersTableSeeder
class you just created.
Let's add a database insert statement to the run
method:
Using Model Factories
Of course, manually specifying the attributes for each model seed is cumbersome.
Instead, you can use ModelFactories to conveniently generate large amounts of database records.
You can use an external factory or use the seeder class factory
attribute.
For example, let's create 50 users and attach a relationship to each user:
Or using directly the factory
attribute without an external factory:
Calling Additional Seeders
Within the DatabaseSeeder
class, you can use the call
method to execute additional seed classes.
Using the call
method allows you to break up your database seeding into multiple files
so that no single seeder class becomes overwhelmingly large.
Simply pass the seeder class you wish to run:
Running Seeders
Once you have written your seeder classes, you may use the db:seed
command to seed your database.
By default, the db:seed
command runs the database_seeder
file, which can be used to call other seed classes.
However, you can use the --seeder
option to specify a specific seeder class to run individually:
You can also seed your database using the migrations:refresh
command,
which will also rollback and re-run all of your migrations.
This command is useful for completely re-building your database:
Cache
The cache functionality is not bundled in the core package but is provided
by the official extension orator-cache
The orator-cache
package provides query results caching to Orator.
It uses the cachy library to ease cache manipulation.
To activate the caching ability you just need to use the provided DatabaseManager
class instead of
the default one and passing it a Cache
instance:
Since the Cache
class is just a subclass of the Cachy CacheManager
class. You can refer
to the Cachy documentation to configure the underlying stores.
Even though, the extension provides a way to cache queries, the invalidation of the caches is the responsability of the developer.
Caching queries
You can easily cache the results of a query using the remember
or remember_forever
methods:
In this example, the results of the query will be cached for ten minutes. While the results are cached, the query will not be run against the database, and the results will be loaded from the default cache driver.
You can also specify which cache driver to use:
If you are using a supported cache driver, you can also add tags to the caches: