-
-
Notifications
You must be signed in to change notification settings - Fork 757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create/update many to many relationship documentation needed #852
Comments
kyle - does that just resolve like this? (example)
Thank you,
Mark Edwards
…On Thu, Apr 5, 2018 at 3:44 PM, Kyle Copeland ***@***.***> wrote:
Hello,
I'm currently evaluating Feathers for our team and love it. I'm trying to
cover all of our use cases and am stumped on how to handle creating or
updating associations between entities with many to many relationships.
I'd like to request for a save and update m to n relationship feathers
example.
Scenario:
There are two services /players and /teams (these are arbitrary resources
I thought of). Players may belong to many teams and Teams have many
players. I'm not sure how to handle associating players with teams in an
elegant fashion.
I'd like to understand how to do the following:
- Add a player to a team
- Remove a player from a team
I am able to setup the association fine:
team.model.js
...
team.associate = function (models) {
team.belongsToMany(models.player, {through: 'PlayerTeam'});
};
...
player.model.js
...
player.associate = function (models) {
player.belongsToMany(models.team, {through: 'PlayerTeam'});
};
...
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#852>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACyd4jo95mdpY5gNYF3GtdghdDwfwG4Uks5tlp40gaJpZM4TJRE4>
.
|
@edwardsmarkf Hey Mark, thanks for reaching out. I think you example might have been left out. |
hi kyle - the image came from here:
https://en.wikipedia.org/wiki/Many-to-many_(data_model) -- maybe
github mail does not allow for photos?
i hope i understood you correctly.
Thank you,
Mark Edwards
…On Thu, Apr 5, 2018 at 5:51 PM, Kyle Copeland ***@***.***> wrote:
@edwardsmarkf <https://github.com/edwardsmarkf> Hey Mark, thanks for
reaching out. I think you example might have been left out.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#852 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACyd4gMY3kJiprvR3I2fRZP7LThfbvLHks5tlrwDgaJpZM4TJRE4>
.
|
forgot to mention:
https://en.wikipedia.org/wiki/Many-to-many_(data_model):
The Author-Book many-to-many relationship as a pair of one-to-many
relationships with a junction table
can your relationship get a "junction table" between them? the junction
table might be able to hold comments, dates, etc. just a thought.
Thank you,
Mark Edwards
…On Thu, Apr 5, 2018 at 6:04 PM, Mark Edwards ***@***.***> wrote:
hi kyle - the image came from here: https://en.wikipedia.org/wiki
/Many-to-many_(data_model) -- maybe github mail does not allow for
photos?
i hope i understood you correctly.
Thank you,
Mark Edwards
On Thu, Apr 5, 2018 at 5:51 PM, Kyle Copeland ***@***.***>
wrote:
> @edwardsmarkf <https://github.com/edwardsmarkf> Hey Mark, thanks for
> reaching out. I think you example might have been left out.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#852 (comment)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ACyd4gMY3kJiprvR3I2fRZP7LThfbvLHks5tlrwDgaJpZM4TJRE4>
> .
>
|
Hey Edward, thanks. Handling the junction table with an ORM/feathers is the issue at hand. Here is my best guess and how to solve the problem with Sequelize. Let me know what you all think.
|
i wonder if this could be better answered at https://sequelize.slack.com ? or use a view instead? please keep me informed as to what you decide is best. it's a very interesting issue. |
That service you are suggesting is actually pretty neat. I sometimes also just create a separate service for the join table model. I wonder if @DesignByOnyx has any insights here from his travels. Creating new related entries should work by passing arrays to |
Thanks for the replies everyone. @daffl for your suggestion, you end up having a team-player service and combine entries through hooks? May you also explain what you mean by creating new related entries via an array? |
@daffl here is my best guess at service vs. ORM service-oriented way:
ORM way:
|
kyle - i am about to run into the same issue you are up against, so please
let me know how this works out for you.
Thank you,
Mark Edwards
…On Fri, Apr 6, 2018 at 11:22 AM, Kyle Copeland ***@***.***> wrote:
@daffl <https://github.com/daffl> here is my best guess at service vs. ORM
service-oriented way:
//AFTER HOOK: pseudo-code I haven't tested this
const {result, app} = context;
result.map(async team => {
const players = await app.service('team-player').find({
query: {
teamId: team.id
}
}).then(results => {
return app.service('player').find({
query: {
playerId: results.playerId
});
});
team.players = players;
})
return context;
ORM way:
// BEFORE HOOK: this works
context.params.sequelize = {
include: [ {
model: context.app.service('player').Model,
as: 'players',
attributes: ['name'],
through: {
attributes: []
}
} ],
raw: false
};
return context;
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#852 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACyd4hzQdRSLJ5tBm7I_BkOFPDYkyhU7ks5tl7JKgaJpZM4TJRE4>
.
|
I know that doesn't seem easy, but I've put a lot of time thinking about all of the use cases and the above is the only way I see about a holistic user-friendly solution. I'm up for suggestions, but you have to contend with established usability conventions (Wordpress, StackOverflow, etc) which allow creating and associating data in a single operation. |
I also think Sequelize makes this a little more difficult than it needs to be. The model methods seem intuitive as a developer but from an API client perspective you just submit data, not call any methods. For example, it is not possible to update or create associations with either an existing id or by giving a list of ids - which I found very counter-intuitive. |
I have this same problem and I have not found something that is easy to use and safe. |
Same problem here, thanks @DesignByOnyx going to go with that approach for now. Anyone else come up with an intuitive solution for this? |
I'm also following this, currently looking to implement this for a new project this week |
@daffl thanks for the suggestion, that worked for me for now. |
Just as a small note, it's actually more complex than @DesignByOnyx indicated - you will likely need to handle deletes as well. One way to accomplish this is to send all tags with each update request, and then to clear any tags associated with the post before saving all tags - this way you're assured to have the correct set of tags saved. The downside is you do quite a bit of unnecessary work on each update (deleting and saving a list of potentially unchanged tags). The only alternative I can think of is reading the relationship before updating, and working out the minimum number of [create, update, deletes] necessary. Might be worth it if you have a large number of tags. I guess another idea is to create a service for the relationship, identify each entry by ID and call independently for each [post, tag] pair. That seems inefficient with network requests but is conceptually a little simpler than trying to do everything at once. |
class CustomService {
constructor(options) {
this.options = options || {};
}
/**
* @params {object} data - Sent in from client
* @params {INT} data.building_id - ID of the building from the Building Model
* @params {INT} data.contact_id - ID of the contact from the Contact Model
*/
create = async (data, params) => {
if (isNaN(data.building_id)) {
throw new errors.BadRequest('Building ID MUST be a Number', data);
}
if (isNaN(data.contact_id)) {
throw new errors.BadRequest('Contact ID MUST be a Number', data);
}
const building = await this.options.building.get(data.building_id);
const contact = await this.options.contact.get(data.contact_id);
const buildingContacts = await building.addContact(contact);
return buildingContacts;
};
}
export default app => {
app.use(
'api/v1/building_contacts',
new CustomService({
building: app.service('api/v1/building'),
contact: app.service('api/v1/contact')
})
);
const buildingContactsService = app.service('api/v1/building_contacts');
buildingContactsService.hooks(hooks);
}; Problem I am facing is that if the contact already exists on the building, i am getting a Any ideas? |
Does this mean you need to create a feathers service for the in-between tables? Seems like an unneeded service. Is there another way of interacting with the database here? |
The "relationship" service is necessary, and every attempt I've made to avoid having as 3rd service has been fruitless or made other code unreasonably difficult. This was the biggest "ah ha" moment I had when dealing with Think about this scenario - you have a blog post and an existing tag and you want to relate the two. You're not creating or updating the blog post itself, and you're not creating or updating the tag - you are simply defining a relationship between the two. You shouldn't need to touch the blog service or the tag service - only the "blog-tags" service... which needs to exist in order for that to happen. The other (more convoluted) option is to try to use the blog service or the tag service to update the relationship. Which one do you use? How do you convey that to your team? If you allow it to happen both ways, now you have twice the code to maintain as well as a difficult mental model. All of these problems go away if you have a 3rd service for the relationship itself. |
I got say. let's make a very easy example, and I hope someone could provide an answer. UI Looks as follow Backend look as follow
Now A user decide to remove "Drama" from PostOne. UI Looks as follow Backend look as follow
How to do this in Sequelize? |
Hello,
I'm currently evaluating Feathers for our team and love it. I'm trying to cover all of our use cases and am stumped on how to handle creating or updating associations between entities with many to many relationships.
I'd like to request for a save and update m to n relationship feathers example.
Scenario:
There are two services /players and /teams (these are arbitrary resources I thought of). Players may belong to many teams and Teams have many players. I'm not sure how to handle associating players with teams in an elegant fashion.
I'd like to understand how to do the following:
I am able to setup the association fine:
team.model.js
player.model.js
The text was updated successfully, but these errors were encountered: