javascriptvue.jsvuejs2vuexvuex-orm

vuexORM hasMany/belongsTo relationship returns null


I believe I have followed the docs correctly.

I have 2 models Author and Book s.t. Author hasMany Book and Book belongsTo Author. The author_id is present in books but the association is empty. Using the Vue Browser add-on, I see the object structure:

$connection:"entities"
$name:"authors"
data:Object
21bc3055-ce90-4119-a68b-9bf2734b596b:Object
$id:"21bc3055-ce90-4119-a68b-9bf2734b596b"
name:"John Doe"
...
books:Array[0]

for books I see e.g.:

$connection:"entities"
$name:"books"
data:Object
0537de72-2381-43b3-9132-831701272054:Object
$id:"0537de72-2381-43b3-9132-831701272054"
title:"Some Book"
...
author_id:"21bc3055-ce90-4119-a68b-9bf2734b596b"

Here are the models:

Author Model:

import { Model } from '@vuex-orm/core'
import Book from './book'

class Author extends Model {
    static entity = 'authors'

    static fields () {
        return {
            id: this.attr(null),
            title: this.attr(null)
...,
            books: this.hasMany(Book, 'author_id')
        }
    }
}

export default Author;

Book Model:

import { Model } from '@vuex-orm/core'
import Author from './author'

class Book extends Model {
    static entity = 'books'

    static fields () {
        return {
            id: this.attr(null),
            name: this.attr(null),
...,
            author_id: this.attr(null),
            author: this.belongsTo(Author, 'author_id')
        }
    }
}

export default Book;

here is store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
import VuexORM from "@vuex-orm/core";
import Author from "./models/author";
import Book from "./models/book";

import * as auth from '../store/modules/auth.js'
import * as authors from './modules/author.js'
import * as books from '../store/modules/books.js'

Vue.use(Vuex);

const database = new VuexORM.Database();
database.register(Author);
database.register(Book);

export default new Vuex.Store({
  plugins: [VuexORM.install(database)],
  modules: {
    auth,
    authors,
    books,
  },
  state: {
  },
  mutations: {
  },
  actions: {
  },
  getters: {
  }
})

Adding an update as I try to figure this out as a manual process.

When I console.log book (as retrieved from vuexORM store), I get:

{…}
title: (...)
created_at: (...)

...


author: Author {$id: '21bc3055-ce90-4119-a68b-9bf2734b596b', id: '21bc3055-ce90-4119-a68b-9bf2734b596b'…}

author_id: "21bc3055-ce90-4119-a68b-9bf2734b596b"

which seems to indicate that the association is intact from the back end, but for whatever reason when it gets inserted in VuexORM, the association is not saved.

here is my code in the store mutation. this console log shows the object being inserted as including the association:

async setBooks(state, books) {
    for (let i=0; i<=books.length-1; i++) {
        const author = await Author.find(books[i].author_id)
        books[i].author = author

        if (i==0) {
            console.log('books[i] is: ', books[i]); // --> SHOWS ASSOCIATION
        }

        await Book.insert({data: books[i]});
    }
},

Once inserted, VuexORM records book.author as null.

How do I save that author association?


Solution

  • You need to tell VuexORM to load the relation in the first place using:

    Book.query().with("author").first()
    

    See the relationships documentation on VuexORM: https://vuex-orm.org/guide/data/retrieving.html#relationships