Avram is the ORM Lucky uses for handling connections to your database, and wrapping the SQL mapping in a friendly Crystal class. An Object Relational Mapping or “ORM”, is a simple way to translate SQL queries, and table schema in to an easy to use object.
Avram currently only supports PostgreSQL with no current plans to support any other RDBMS. However, Lucky does not require you to use Avram if your requirements are a bit different.
Originally called “LuckyRecord”, the name change was decided because this ORM is not tied directly to the Lucky framework. You could choose to use it in any number of other Crystal frameworks. When deciding the name, we wanted something easily searchable, and meaningful. Thanks to all the suggestions from the community, we landed on Avram.
Henriette Avram was a computer programmer and systems analyst who developed the MARC format the international data standard for bibliographic and holdings information in libraries.
Every ORM will have a different pattern, and different set of tools included. With Avram, we took a
pattern breaking out where business logic is stored vs. where database queries are handled. This pattern
helps to keep code organized by it’s purpose within your application. This includes
Avram’s models use classes to map each database table to a specific object. The naming convention for
each model is to be the singular word as where the table name is the plural form.
User model, and
A model inherits from
Avram::Model; however, Lucky will generate an abstract class called
for you to inherit from. This abstraction layer allows you to apply special callbacks, attributes,
or methods to all of your models.
Avram queries are classes that encompass querying the database. Once you have data in your database,
you’ll need a way to pull that data back out, and a Query class is that way! The naming convention
for these objects is to use the referencing model’s name followed by
Query objects inherit from a subclass of the model called
BaseQuery. If you create a
Lucky will create a
User::BaseQuery class for you, and your
UserQuery object will inherit from that.
UserQuery < User::BaseQuery).
Avram operations are classes used for creating and updating records in the database.
Similar to the
Query object, these classes will inherit from a subclass of your model called
SaveOperation. If you create a
User model, Lucky will create a
User::SaveOperation class for you.
SaveUser < User::SaveOperation).
The naming convention for operations is to use an action of what this object does like save a user record.
You can think of migrations like git for your database. These are classes that are scoped with a timestamp to allow you to update your database in versions as well as undo changes that you’ve made previously while keeping track of the order you made them in.
Unlike the other files which live in your app’s
src/ folder, these are located in the
Avram factories are classes that you can use for generating data quick. The most common use cases are when writing tests for your application, and when seeding your database with some default or placeholder data.
Factories inherit from
Avram::Factory and follow the naming convention using the name of the model they
reference followed by “Factory”. (e.g.
UserFactory factory) You’ll find these located in your app’s
Even though Lucky uses Avram by default which only supports PostgreSQL, Lucky does not enforce the use of it. There may be cases where your application doesn’t even need a database (e.g. luckyframework.org).
If you want to take advantage of some of what Lucky has to offer, but your requirements need MySQL, SQLServer, or maybe something like RethinkDB / MongoDB, here’s a few tips to integrating those.
src/app_database.crcan be deleted to avoid confusion
config/database.crfile with the new adapter’s configuration settings
# config/database.cr class UnusedDB < Avram::Database end UnusedDB.configure do |settings| settings.credentials = Avram::Credentials.void end Avram.configure do |settings| settings.database_to_migrate = UnusedDB end # Configure your actual settings here MyOtherAdapter.configure do |settings| # Refer to that adapter's configuration guide settings.url = "my_other_adapter_url" end
If your app doesn’t need a database, you should still set the
AppDatabasecredentials setting to
Avram::Credentials.void. Avram Operations can still be quite useful for things like contact forms, or email subscribe forms. See this website for an example.