GithubHelp home page GithubHelp logo

Comments (19)

daffl avatar daffl commented on May 13, 2024

I am not too familiar with the more complex side of Sequelize but looking at the Relations/Associations docs, once you associated an m:n relationship you could just register a service that gets the related entities:

app.use('/api/v1/intents/:intentId/entities', {
  find(params) {
    const id = params.intentId;
    return app.service('intents').get(id)
      .then(intent => intent.getEntities());
  },

  setup(app) {
    this.app = app;
  }
});

from feathers-sequelize.

ekryski avatar ekryski commented on May 13, 2024

@lionelrudaz or you can just do that same call to the intents service in a before hook of a entities service. We have found that you rarely need to nest routes like that and instead should have them flatter and use something like an intentId. See http://docs.feathersjs.com/middleware/routing.html#nested-routes.

So you'd have:

function getIntents() {
  return function(hook) {
    return Prmise(function(resolve, reject) {
      hook.app.service('intents').get(hook.params.query.intentId).then(result => {
         hook.params.intent = result;
         resolve(hook);
      }).catch(reject);
    };
  };
}

app.use('intents', service());
app.use('intent_entites', service());

app.service('intent_entities').before({
  find: [
    getIntents()
  ]
})

That should more or less do it.

from feathers-sequelize.

ekryski avatar ekryski commented on May 13, 2024

I'm going to close this as both of those options should work. @lionelrudaz can you report back to let us know if one of those works or not? If not, we can re-open and dig deeper.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

Thanks both of you for your answers.

I tried both options, can't make work either of them.

@daffl, theoretically, everything should work as you suggest. The thing is that I believe the relationship is somehow unknown at this step. I get the following error:

TypeError: intent.getEntities is not a function

Here's how I set the relationships up in services/index.js:

/* jshint esversion: 6 */

import language from './language';
import conversation from './conversation';
import message from './message';
import category from './category';
import intent from './intent';
import entity from './entity';
import intententity from './intent-entity';

import Sequelize from 'sequelize';

export default function() {
  const app = this;

  const sequelize = new Sequelize(app.get('postgres'), {
    dialect: 'postgres',
    logging: console.log
  });

  app.set('sequelize', sequelize);

  app.configure(language);
  app.configure(message);
  app.configure(conversation);
  app.configure(category);
  app.configure(intent);
  app.configure(entity);
  app.configure(intententity);

  let models = sequelize.models;
  models.intent.belongsToMany(models.entity, {through: 'IntentEntity'});
  models.entity.belongsToMany(models.intent, {through: 'IntentEntity'});

  sequelize.sync();
}

I imagine that on IntentEntity service, the relationship is unknown. I tried to move the relationship before configuring IntentEntity service, but that doesn't change anything.

Any ideas?

@ekryski: your solution will work as a charm with a 1:n relationship. The thing is that I don't have an intentId column in my Entities model, so that can't work like that, unless I'm missing a point. But working with flat URLs can work as well, no problem. It doesn't change the root question: how can I make a query with a join on the relationship table?

Let me know if you need anything else.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

Hi guys,

I tried a few other workarounds, but I'm unable to make that work. Am I the only one in that situation? Haven't you been in front of many-to-many relationships? I can't find any example that helped me so far.

Thanks again for your help.

Cheers,

Lionel

from feathers-sequelize.

daffl avatar daffl commented on May 13, 2024

For me not with Sequelize. Did you get some test code working with just the plain model definitions as described in the Sequelize documentation?

from feathers-sequelize.

ekryski avatar ekryski commented on May 13, 2024

@lionelrudaz I'll try and cook up a demo app to see if I can get this sorted. In all honesty I haven't run into many-to-many relationships all that often.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

@daffl I can try again with a very simple application to see if it behaves correctly. From that part, I think that the association is not yet available when I work in the services. I don't know if it helps.

@ekryski Do you want a link to my app? Maybe it can help.

from feathers-sequelize.

ekryski avatar ekryski commented on May 13, 2024

@lionelrudaz sure that would help.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

Here you go: https://github.com/lionelrudaz/wellnow-node

from feathers-sequelize.

ekryski avatar ekryski commented on May 13, 2024

@lionelrudaz took a quick look. Overall looks really good! Makes me really happy to see how someone else is using Feathers. I'll take a more detailed look a little later today just in the middle of working on authentication right now. I think we should be able to solve this pretty easily.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

No problem.

Your new example really helps building beautiful apps from the ground up. I just modified the structure to add a models folder, because I found that cleaner.

Let me know if I can be from any help.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

I worked a bit this evening. I believe the key is that associations aren't existing when I do this in my intent entity service:

app.use('/api/v1/intents/:intentId/entities', {
    find(params) {
      const id = params.intentId;
      return app.service('api/v1/intents').get(id)
        .then(intent => intent.getEntities());
    }
  });

It still tells me that there's no getEntities method for intent. My conclusion is that the intent service provides a model instance and that this model instance doesn't know the relationship with Entity.

I tried to move a bit the logic, by loading models from an index.js file in my models folder. In parallel, I removed the connection with the DB in the services. I changed the intent, entity and intent entity services to use the models that I instantiate from the models module.

I also added a new IntentEntity model to take care of the relationship.

I'm still at the same stage, so I don't know if you have any clue.

I uploaded my work in a new branch: https://github.com/lionelrudaz/wellnow-node/tree/many-to-many

Let me know if you need more information.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

OK, I think I made it.

My idea: load all models with index.js in the models folder. Set the associations right there.

Then, for the particular services using a many-to-many relationship, I can do this:

app.use('/api/v1/intents/:intentId/entities', {
    find(params) {
      const id = params.intentId;
      return models.entity.findAll({
        include: [
           { model: models.intent, where: { id: id }}
        ]
      });
    },
    create(data, params) {
      const id = params.intentId;
      return models.entity.create(data).then(function(entity) {
        entity.addIntent(id);
        return entity;
      });
    }
  });

Can you briefly tell me it's not horrible and that I can proceed with the next services that have these kinds of associations?

My app is updated there: https://github.com/lionelrudaz/wellnow-node

Thanks in advance

from feathers-sequelize.

ekryski avatar ekryski commented on May 13, 2024

@lionelrudaz Woot! If it's working then it definitely looks good to me. 😄 Nice work.

I'm busy working on the news Feathers website so sorry I didn't really have time to play around with Many-to-many relationships.

from feathers-sequelize.

lionelrudaz avatar lionelrudaz commented on May 13, 2024

No problem, totally get it. All the best for the new website. I close then

from feathers-sequelize.

lopezjurip avatar lopezjurip commented on May 13, 2024

On client side, params.intentId is undefined.

const io = require('socket.io-client');
const feathers = require('feathers/client');
const hooks = require('feathers-hooks');
const socketio = require('feathers-socketio/client');
const authentication = require('feathers-authentication/client');

const socket = io('http://localhost:3030');
const client = feathers()
  .configure(hooks())
  .configure(socketio(socket))
  .configure(authentication());

client.service('/api/v1/intents/:intentId/entities').find({ intentId: 1 })
  .then(entities => console.log(entities))
  .catch(err => console.error(err));

But with server-side feathersjs app instance, the param intentId is passed correctly.

from feathers-sequelize.

daffl avatar daffl commented on May 13, 2024

Can you create a new issue for that? This is kind of a bug (because only params.query is passed between client and server) but I am not sure how to solve that yet. A workaround is to map it to params.query.intendId.

from feathers-sequelize.

lopezjurip avatar lopezjurip commented on May 13, 2024

Issue: feathersjs/feathers#304

from feathers-sequelize.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.