Skip to content

How to work models with relationships? #117

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

Closed
geoidesic opened this issue Dec 14, 2019 · 8 comments
Closed

How to work models with relationships? #117

geoidesic opened this issue Dec 14, 2019 · 8 comments
Labels
question Further information is requested stale

Comments

@geoidesic
Copy link

geoidesic commented Dec 14, 2019

I'm confused about how to work models and relationships.

So for example, I have a form, which stores a related model id as 'enquiry_type_id. However when I fetch data via jsonapi-vuex this key is missing from the attributes, instead I'm supposed to get it via getRelated`? (I think). But then how do I map that back to my vue-component's model?

So I have a component declared like this (pug syntax):

q-select(
                  label="Enquiry type"
                  :value="form.enquiry.enquiry_type_id"
                  @input="enquiryUpdater('enquiry_type_id', $event)"
)

enquiryUpdater looks like this:

enquiryUpdater(fieldName, ev) {
      this.$set(this.form.enquiry, fieldName, ev.value);
},

When I load the form I'm doing:

this.$set(this.form, "enquiry", this.$store.getters['enquiries/get']('enquiries/1'));

... but that value is failing to load because it's not present in the vuex store as an attribute, only as a relationship.

Probably I'm doing it all wrong but I can't think of a better way. You mentioned something about using getters and setters instead of a data model but I don't know how that would look or work. For example when I'm editing the form it has to write to a model for that q-select component, so what would my component's :value prop and @input function look like in order to integrate with jsonapi-vuex's relationships?

@geoidesic
Copy link
Author

geoidesic commented Dec 14, 2019

I found a work-around but it's unwieldy. After fetching remote data via jsonapi-vuex I then read the store into my model manually:

      this.$set(
        this.form,
        "enquiry",
        this.$store.getters[`enquiries/get`](`enquiries/${this.enquiry_id}`)
      );

      this.form.enquiry.enquiry_type_id = parseInt(
        this.$store.getters[`enquiries/getRelated`](
          `enquiries/${this.enquiry_id}`
        )["enquiry_type"]._jv.id
      );

@mrichar1
Copy link
Owner

mrichar1 commented Jan 6, 2020

The usual way to get all related data without having to make a separate getRelated request is to use the include functionality provided by the jsonapi spec: https://jsonapi.org/format/#fetching-includes
jsonapi-vuex will automatically add any records in the include section to the store.

You probably want something like this (where the include param is the name of the relationship):

this.$store
  .dispatch('jv/get', ['blog/1', { params: { include: 'author' }])
  .then((data) => {
    console.log(data)
  })

@mrichar1 mrichar1 added the question Further information is requested label Jan 13, 2020
@geoidesic
Copy link
Author

geoidesic commented Feb 27, 2020

What about when you're trying to persist related data via POST?

I'm trying to figure out how to do that but I've drawn a blank. Can't see anything about that in the docs. Let's say e.g. I have Enquiries and People as an m2m relationship in my database via a link table. Now I'm creating a new Enquiry on the front-end and in the process, I want to also:

A. find and link some people to that enquiry
B. insert some people and link them to the enquiry

I can see that the JSONAPI spec supports A, but I can't see how to achieve that using this library (none of the examples for POST show adding related data).

I'm aware that the JSONAPI spec does not support B... but I'm concerned about that because I can't think of a way to make my architecture work without that – please see my comment here with more detail explaining the problem with this: json-api/json-api#1435 (comment)

@geoidesic
Copy link
Author

I have yet to confirm that it works but there's an example here: https://codingitwrong.com/2018/06/18/vuex-jsonapi-a-zero-config-data-layer.html#writing-data

@mrichar1
Copy link
Owner

mrichar1 commented Mar 6, 2020

Yes you're right as I understand the spec - you can add relationships in a POST (create) that link to existing items, but you can't make a post that creates multiple items all in one go. There are some extensions to the JSONAPI spec that could allow this, but I've not used any of them so I don't know how they would interact with this library.

I think in your case you would have to write some extra code to work out the network graph of relationships, and then ensure that POSTs for the various new items were added in the correct order.

As to how jsonapi-vuex handles relationships in POST requests...

When you make a POST the server, jsonapi-vuex looks at the response and either returns the data from the server (if it's a 201 with content) or otherwise returns the original data you posted.
Either way, this data will contain the relationships which will be contained in the store - though if the related items aren't in the store, asking for them will just return an empty object until the store does contain them.

If you have used include= in your POST, and the server hands back data, then the includes will be processed and added to the store, and everything should 'just work'.

@geoidesic
Copy link
Author

Ok tx, what about PATCH for relationships? How would I set the ids of the related items for the request?

@mrichar1
Copy link
Owner

mrichar1 commented Mar 7, 2020

The simplest approach is just to update the relationships section in a PATCH and the server/store will sort it out. There's a plan to provide a way to PATCH via relationship URLs in #88 but this hasn't been implemented yet.

@stale
Copy link

stale bot commented May 6, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label May 6, 2020
@stale stale bot closed this as completed May 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested stale
Projects
None yet
Development

No branches or pull requests

2 participants