2

How can I automatically append a property from a relation to the root object, as if it were a column from the same table but actually it is coming from another table.

Supose I have an User model that hasMany Emails.

How can I only append the email from the first Email of the User model, so that everytime I query the User model I get it like a property?

Example:

What I'm doing:

(await User.query().where('id', id).with('emails').first()).toJSON()
{
  "name": "Eleandro Duzentos",
  "emails": [
    { "email": "eleandro@inbox.ru" },
    { "email": "eleandro@mail.ru" }
  ]
}

What I want:

(await User.find(id)).toJSON()
{
  "name": "Eleandro Duzentos",
  "email": "eleandro@inbox.ru"
}

Obs: I'm not putting the email on the same table because, there's a chance that a user may need more then one email in a long future, but for now, it has only one.

How can I do that?

Eleandro Duzentos
  • 1,370
  • 18
  • 36

2 Answers2

1

For the customized JSON response i would suggest the use of serializers. You can override the default serializers to get the desired result.

You can refer to this - https://adonisjs.com/docs/4.0/serializers

SBN
  • 123
  • 7
0

Here is my code. You could be inspired by it:

Model User:

...
const Email = use('App/Models/Email')

class User extends Model {

  async getEmails() {
    let list = []

    let emails = await Email.query().where('user_id', this.id).fetch()
    emails.rows.forEach(email => {
      list.push({ name: this.username, email: email.email })
    });

    return list
  }

  emails() {
    return this.hasMany('App/Models/Email')
  }
}

module.exports = User

Controller :

...

let user = await User.find(1)
return await user.getEmails()

Output :

[
   {"name":"CrBast","email":"test@crbast.ch"},
   {"name":"CrBast","email":"test2@crbast.ch"}
]

Feel free to correct me if that's not what you want :)

crbast
  • 2,192
  • 1
  • 11
  • 21
  • 1
    I just want to get the first email, since for now, an user will only have one email. What I want is to get the email as a field of the user even if it is comming from another `model/table`. In your code, I need to call a second method that returns a list. What I want is to `await User.find(id)` and automatically get the first user email appended as a field as if it was coming from a column on the `users` table. So, instead of get the first user email by `user.emails[0]` I want to use `user.email`, some kind o computed property, but from a relation. – Eleandro Duzentos Nov 21 '19 at 10:05
  • I don't have the knowledge to help you with exactly what you want. If you don't have any other answers, I advise you to post it on `forum.adonisjs.com`. I'll be here if you need any help. – crbast Nov 21 '19 at 18:13
  • This documentation could help you: https://adonisjs.com/docs/4.1/traits#_extending_a_models_methods – crbast Nov 21 '19 at 18:13