How to access data in a `through` table with a bookshelf

I am using [BookshelfJS] [bookshelfjs] for my ORM and I am wondering how to access data in a table though

.

I have 3 models Recipe

, Ingredient

and RecipeIngredient

which connect the two.

var Recipe = BaseModel.extend({
  tableName: 'recipe',

  defaults: { name: null },

  ingredients: function () {
    return this
      .belongsToMany('Ingredient')
      .through('RecipeIngredient')
      .withPivot(['measurement']);
  }
}));

var Ingredient = BaseModel.extend({
  tableName: 'ingredients',

  defaults: { name: null },

  recipes: function () {
    return this
      .belongsToMany('Recipe')
      .through('RecipeIngredient');
  }
}));

var RecipeIngredient = BaseModel.extend({
  tableName: 'recipe_ingredients',

  defaults: { measurement: null },

  recipe: function () {
    return this.belongsToMany('Recipe');
  },

  ingredient: function () {
    return this.belongsToMany('Ingredient');
  }
}));

      

Then I try to get Recipe

along with all Ingredients

, but I can not decide how to access measurement

to RecipeIngredient

.

Recipe
  .forge({
    id: 1
  })
  .fetch({
    withRelated: ['ingredients']
  })
  .then(function (model) {
    console.log(model.toJSON());
  })
  .catch(function (err) {
    console.error(err);
  });

      

Return:

{
  "id": 1,
  "name": "Delicious Recipe",
  "ingredients": [
    {
      "id": 1,
      "name": "Tasty foodstuff",
      "_pivot_id": 1,
      "_pivot_recipe_id": 1,
      "_pivot_ingredient_id": 1
    }
  ]
}

      

No value measurement

.

I thought the method .withPivot(['measurement'])

would have captured this value, but it doesn't return any additional data.

Am I missing something or am I misunderstanding how this works?

0


source to share


1 answer


I'm not really sure why you want to use through

. If it's just a basic many-to-many mapping, you can achieve this by doing the following:

var Recipe = BaseModel.extend({
  tableName: 'recipe',

  defaults: { name: null },

  ingredients: function () {
    return this
      .belongsToMany('Ingredient').withPivot(['measurement']);
  }
}));

var Ingredient = BaseModel.extend({
  tableName: 'ingredients',

  defaults: { name: null },

  recipes: function () {
    return this
      .belongsToMany('Recipe').withPivot(['measurement']);;
  }
}));

      

You don't need an additional model for the join table. Just remember to define the join table in your database as ingredients_recipe

(alphabetically by joining table names!). Or you can provide your own name for the function belongsToMany

, for which the junction table must be named. Be sure to have ingredients_id

and recipe_id

iningredients_recipe



That's pretty much it. Then you can do

Recipe
  .forge({
    id: 1
  })
  .fetch({
    withRelated: ['ingredients']
  })
  .then(function (model) {
    console.log(model.toJSON());
  })
  .catch(function (err) {
    console.error(err);
  });

      

+4


source







All Articles