Search code examples
reactjsreduxredux-orm

How to create a new instance of a model along with relations in redux-orm?


When using redux-orm, how does one add related data during the creation of a model instance?

For example given the following two models:

// User
import {fk, many, Model} from 'redux-orm';
export default class User extends Model {
    static modelName = 'User';

    static fields = {
        pets: many('Pet', 'pets'),
    };
}

// Pet
import {fk, many, Model} from 'redux-orm';

export default class Pet extends Model {
    static modelName = 'Pet';

    static fields = {
        user: fk('User', 'pets'),
    };
}

My create reducer in the pet model looks like:

        case 'PET/CREATE':
            const newPet = Pet.create(action.payload);
            newPet.user.add(action.parentId); // parentId is the user id
            break;

This however results in an error, as newPet.user is undefined. I have also tried withRefs

        case 'PET/CREATE':
            const newPet = Pet.create(action.payload).withRefs;
            newPet.user.add(action.parentId); 
            break;

I have also attempted to re-lookup the id:

        case 'PET/CREATE':
            const newPet = Pet.create(action.payload);
            // console.log(newPet.id); // correctly outputs id
            Pet.withId(newPet.id).user.add(action.parentId);
            break;

EDIT

Found that I can do

const newPet = Pet.create({ ...action.payload, user: action.parentId });

But not positive that is the right approach and if its actually correctly linking, so leaving the question open for now.


Solution

  • "Manually" passing in the related ID value for the relation field is one way to do it. Another is to create the first model, then pass the first model instance to the second model instance either during or after creation:

    const fred = User.create({name : "Fred"});
    
    // Pass during creation
    const pet = Pet.create({name : "Spot", user : fred});
    
    // Or after creation
    const pet = Pet.create({name : "Spot"});
    pet.user = fred;
    
    // Then ask Redux-ORM to apply queued updates and return the updated data
    return session.reduce();
    

    edit

    Update: I've published a couple posts on Redux-ORM as the first two parts of a series on "Practical Redux", discussing techniques I've developed from my own experience with Redux.