Integrating Jennifer & Amber v1.0+
Tags: crystal, crystallang, amber, webdev
Published: 2023-12-04 16:28:59

---
title: Integrating Jennifer & Amber v1.0+
published: true
date: 2023-12-04 13:09:23 UTC
tags: crystal, crystallang, amber, webdev
canonical_url: https://seesethcode.com/integrating-crystal-active-record-orm-with-amber
---

To get the full experience with Jennifer, we'll first want to install `sam`. This is Jennifer's CLI tool that has generators for creating models, managing the db creation/resetting, migrations, etc. that aren't currently able to be added quickly and easily into the Amber CLI. So this gives users a way to still have the CLI conveniences of a framework. The nice part is that once `sam` is installed and working, this also means Amber will work.

First, add the `sam` shard to your `shards.yml`, it should be added under the "development dependencies" sections like this:

```
development_dependencies:
  ameba:
    github: crystal-ameba/ameba
    version: ~> 1.5.0
  sam:
    github: imdrasil/sam.cr
    version: ~> 0.5.0

```

Next, remove the entry for `granite` and `citrine-i18n`, and add the shards for Jennifer and your database adapter of choice. Your `dependencies` section should look like this on a brand new Amber app:

```
dependencies:
  amber:
    github: amberframework/amber
    version: 1.4.1 # Make sure to use the latest version of Amber here

  quartz_mailer:
    github: amberframework/quartz-mailer
    version: ~> 0.8.0

  jasper_helpers:
    github: amberframework/jasper-helpers
    version: ~> 1.2.2 

  jennifer:
    github: imdrasil/jennifer.cr
    version: "~> 0.13.0"

  pg:
    github: will/crystal-pg
    version: ~> 0.26.0

  # Uncomment to use MySQL. Note: on MySQL v8, this shard does not support the v8 authentication protocol, you'll want to run:
  # `mysql --default-auth=mysql_native_password` for MySQL to work properly
  #mysql:
    #github: crystal-lang/crystal-mysql
    #version: ~> 0.14.0

  # Uncomment to use sqlite
  #jennifer_sqlite3_adapter:
    #github: imdrasil/jennifer_sqlite3_adapter
    #version: "~> 0.4.0"

```

Save your `shard.yml` file at this point.

Next, create a new file in your projects root folder called `override.shard.yml` and save the following into the file:

```
i18n:
  github: crimson-knight/i18n.cr
  branch: master

```

You can now install your shards by running `shards install`.

You may get something like the warning below:

```
Shard "ameba" may be incompatible with Crystal 1.10.1

```

You can usually safely ignore this warning, or adjust the version down until the warning goes away. Eitherway, it's safe to move on.

Next, we are going to change the file contents of the `config/database.cr` file to the following:

```
require "jennifer"
require "jennifer/adapter/postgres" # for PostgreSQL
# require "jennifer/adapter/mysql" for MySQL
# require "jennifer/adapter/sqlite" for SQLite

# This allows for easy test db use when running the `crystal spec` command
{% if @top_level.has_constant? "Spec" %}
  APP_ENV = "test"
{% else %}
  APP_ENV = ENV["APP_ENV"]? || "development"
{% end %}

Jennifer::Config.configure do |conf|
  conf.read("config/database.yml", APP_ENV)
  conf.from_uri(ENV["DATABASE_URI"]) if ENV.has_key?("DATABASE_URI")
  conf.pool_size = (ENV["DB_CONNECTION_POOL"] ||= "5").to_i
  conf.logger.level = APP_ENV == "development" ? Log::Severity::Debug : Log::Severity::Error
end

```

Next, we'll want to create the file containing our database connection details. This will look very similar to the database configuration in a Rails app, but don't be fooled! These are not identical :)

Create the file `config/database.yml` with the following contents, updated with your apps details. None of the databases need to be created yet, just put what you'd like your app databases to be called. If you use an existing database, it should still connect with the correct details.

```
default: &default
  host: localhost
  user: user_name # On Mac, this is the results from a fresh terminal session when you run `whoami`
  password: user_password # On Mac, this is blank by default, use empty quotes '' for this.
  adapter: postgres # or `mysql`, or `sqlite` without quotes

development:
  <<: *default
  db: application_database_name_development

test:
  <<: *default
  db: application_database_name_test

production:
  <<: *default
  db: application_database_name_production

```

Finally, we'll want to modify the `sam.cr` file found in your projects root after installation the shards.

The contents should look like this:

```
#!/bin/crystal

require "./config/database.cr" # here load jennifer and all required configurations
require "sam"
load_dependencies "jennifer"

# Here you can define your tasks
# desc "with description to be used by help command"
# task "test" do
# puts "ping"
# end

```

You should now be able to run: `crystal run sam.cr help` from the projects root in your command line and see output something like this:

```
 jennifer_config crystal sam.cr help
Name Description
------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------
help | Prints description for all tasks
generate:makefile | Generates makefile extension. Now command could be executed via `make sam your:command argument`
generate:migration | Generates migration template. Usage - generate:migration <migration_name>
generate:model | Generates model and migrations template. Usage - generate:model <ModelName>
db:migrate | Will call all pending migrations
db:step | Invoke next migration. Usage: db:step [<count>]
db:rollback | Rollback migration. Usage: db:rollback [v=<migration_exclusive_version> | <count_to_rollback>]
db:drop | Drops database
db:create | Creates database
db:seed | Populate database with default entities.
db:setup | Runs db:create, db:migrate and db:seed
db:version | Prints version of the last run migration
db:schema:load | Loads database structure from the structure.sql file

```

If you've run into any errors, double check that you've saved all of the files with the most recent changes, and that there are no typos.

_Important Note_

Check in the `src/` folder to see if there is already a `models` folder. As of Amber v1.4 the `new` command does not create this folder and this is the destination for models being created by `generate:model`.

Once you create the `src/models` folder, you should now be able to generate a model:

I like to build sam once and then re-run it. If you change anything in the `sam.cr` file, you'll need to recompile to pick up any changes outside of yml files.

```
crysatl build sam.cr


./sam generate:model example_model name:string


./sam db:create


./sam db:migrate

```

Your database should now be setup and operational with basic generators for `Jennifer` working.

And, you're done! Your app should now work with Jennifer. The Amber CLI and `sam` don't yet work together, but the controller and view generators should get you very close to a working initial template with only minor changes to make your app compile.

Make sure to use same for creating/seeding/migrating your database.