Adonis LUCID ORM
Tags: javascript, adonisjs, lucid, orm
Published: 2023-08-11 17:32:51

Adonis Lucid ORM is a powerful object-relational mapping (ORM) system that comes with the AdonisJS framework. It simplifies database interactions and provides an elegant way to work with your database tables and records. Below, I'll provide you with an introduction to Adonis Lucid ORM and some examples of how to use it.

### Setting Up Models and Migrations

1. **Creating a Model and Migration**: To get started, you need to create a model and its corresponding database table migration. Use the following command to generate both:

   ```
   adonis make:model Article -m
   ```

   This command creates an `Article` model along with a migration file.

2. **Defining Migration Schema**: Open the generated migration file (e.g., `database/migrations/xxx_create_articles_table.js`) and define the schema for your `articles` table. Example:

   ```javascript
   'use strict';

   const Schema = use('Schema');

   class CreateArticlesTableSchema extends Schema {
     up() {
       this.create('articles', (table) => {
         table.increments();
         table.string('title').notNullable();
         table.text('content');
         table.timestamps();
       });
     }

     down() {
       this.drop('articles');
     }
   }

   module.exports = CreateArticlesTableSchema;
   ```

3. **Running Migrations**: Run the migrations to create the `articles` table in your database:

   ```
   adonis migration:run
   ```

### Working with Models

Now that you have your model and table set up, you can start working with your articles using the Adonis Lucid ORM.

1. **Creating Records**:

   ```javascript
   const Article = use('App/Models/Article');

   const newArticle = new Article();
   newArticle.title = 'Introduction to Adonis Lucid ORM';
   newArticle.content = 'Adonis Lucid ORM makes database interactions easy.';
   await newArticle.save();
   ```

2. **Querying Records**:

   ```javascript
   const articles = await Article.all(); // Get all articles

   const article = await Article.find(1); // Get article by ID

   const articlesWithTitle = await Article.query().where('title', 'like', '%Adonis%').fetch(); // Get articles with title containing 'Adonis'
   ```

3. **Updating Records**:

   ```javascript
   const article = await Article.find(1);
   article.title = 'New Title';
   await article.save();
   ```

4. **Deleting Records**:

   ```javascript
   const article = await Article.find(1);
   await article.delete();
   ```

5. **Relationships**:

   You can define relationships between models, such as one-to-many, many-to-many, etc. For example, if you have a `Comment` model, you can define a relationship between `Article` and `Comment`.

   ```javascript
   // Article.js
   class Article extends Model {
     comments() {
       return this.hasMany('App/Models/Comment');
     }
   }

   // Comment.js
   class Comment extends Model {
     article() {
       return this.belongsTo('App/Models/Article');
     }
   }
   ```
**Many to Many**:
In Adonis Lucid ORM, setting up a many-to-many relationship between two models involves creating an intermediary table that holds the relationships between instances of the two models. Let's go through an example of setting up a many-to-many relationship between `User` and `Role` models.

Assuming you have already created the `User` and `Role` models, follow these steps to set up the many-to-many relationship:

1. **Define the Relationships**:

In your `User` model (`app/Models/User.js`):

```javascript
class User extends Model {
  roles() {
    return this.belongsToMany('App/Models/Role');
  }
}
```

In your `Role` model (`app/Models/Role.js`):

```javascript
class Role extends Model {
  users() {
    return this.belongsToMany('App/Models/User');
  }
}
```

2. **Create the Migration for the Intermediary Table**:

Generate a migration to create the intermediary table for the many-to-many relationship. Run the following command:

```
adonis make:migration create_role_user_pivot_table
```

Open the generated migration file (e.g., `database/migrations/xxx_create_role_user_pivot_table.js`) and define the schema for the intermediary table:

```javascript
'use strict';

const Schema = use('Schema');

class CreateRoleUserPivotTableSchema extends Schema {
  up() {
    this.create('role_user', (table) => {
      table.increments();
      table.integer('role_id').unsigned().references('id').inTable('roles');
      table.integer('user_id').unsigned().references('id').inTable('users');
      table.timestamps();
    });
  }

  down() {
    this.drop('role_user');
  }
}

module.exports = CreateRoleUserPivotTableSchema;
```

3. **Run the Migration**:

Run the migration to create the intermediary table:

```
adonis migration:run
```

4. **Working with Many-to-Many Relationship**:

Now you can work with the many-to-many relationship between `User` and `Role`:

```javascript
const user = await User.find(1);
const roles = await user.roles().fetch(); // Get roles associated with the user

const role = await Role.find(1);
const users = await role.users().fetch(); // Get users associated with the role

// Attaching and detaching relationships
await user.roles().attach([1, 2]); // Attach roles
await user.roles().detach([1]); // Detach roles
```

Remember to replace `1` and `2` with the actual IDs of roles and users.

By setting up this many-to-many relationship, you can easily manage associations between users and roles using Adonis Lucid ORM. 

**Understanding Eager Loading in Adonis Lucid ORM**

When working with databases, efficient data retrieval is crucial to maintaining application performance. Eager loading is a technique used in Adonis Lucid ORM to retrieve related data along with the main data in a single query, reducing the number of database queries and improving response times. This article introduces eager loading and how to use it effectively in Adonis Lucid ORM.

**What is Eager Loading?**

Eager loading is a method for fetching related data upfront while querying the main dataset. This prevents the common problem of the "N+1 query" issue, where an initial query is followed by additional queries to fetch related data for each result, leading to performance degradation.

**Eager Loading in Adonis Lucid ORM**

Adonis Lucid ORM provides a convenient way to perform eager loading through the `with` method. This method allows you to specify the relationships you want to load along with the main query.

**Example Usage:**

Imagine you have a `Post` model that belongs to a `User`, and you want to retrieve a collection of posts along with their associated users. Without eager loading, this could lead to numerous queries. However, with eager loading, you can optimize this process:

```javascript
const posts = await Post.query().with('user').fetch();
```

In this example, the `with('user')` method call tells Adonis Lucid ORM to include the related `user` data for each fetched `post`, resulting in a more efficient query.

**Eager Loading Multiple Relationships:**

You can also eager load multiple relationships simultaneously:

```javascript
const posts = await Post.query().with(['user', 'comments']).fetch();
```

This fetches posts along with their associated users and comments in a single query.

**Deep Eager Loading:**

For more complex scenarios, you can perform deep eager loading to fetch nested relationships:

```javascript
const users = await User.query().with('posts.comments').fetch();
```

This retrieves users along with their posts and associated comments.

**Benefits of Eager Loading:**

1. **Performance**: Eager loading significantly reduces the number of queries, leading to improved performance and reduced latency.

2. **Code Readability**: Eager loading enhances code readability by consolidating related data fetching in a single query.

3. **Fewer Database Connections**: Fewer queries mean fewer database connections, reducing strain on your database server.

**Conclusion:**

Eager loading is a powerful tool in Adonis Lucid ORM that allows you to optimize data retrieval by fetching related data in a single query. By minimizing the "N+1 query" problem, you can improve application performance and provide a smoother user experience. Understanding and utilizing eager loading effectively can lead to more efficient and maintainable database interactions in your AdonisJS applications.

In conclusion, eager loading is a vital technique in the realm of database interactions, and Adonis Lucid ORM makes it easy to implement within your applications. By fetching related data alongside the main dataset in a single query, you can dramatically improve performance, reduce the number of database queries, and enhance the responsiveness of your application.

The power of eager loading lies not only in its ability to optimize data retrieval but also in its impact on code readability and maintainability. By consolidating related data fetching within a single query, your code becomes cleaner and more comprehensible. This contributes to the long-term maintainability of your application, as future developers can quickly understand how data is being accessed and utilized.

In Adonis Lucid ORM, eager loading is achieved through the `with` method, which can be used for loading one or more relationships, as well as deeply nested relationships. Whether you're retrieving related user profiles, comments on posts, or any other type of associated data, eager loading empowers you to do so efficiently and elegantly.

By implementing eager loading in your AdonisJS projects, you're not only optimizing performance but also adhering to best practices in database interaction. This technique plays a pivotal role in building responsive, efficient, and well-structured applications, ultimately enhancing the user experience and contributing to the overall success of your software endeavors.

That's all for questions and more please don't hesitate to comment it bellow.