Creating join table relationship, with attributes

#1

Hello,

We use jsonapi-resources gem for our Ruby on Rails API, which implements json:api, apologies if this is the wrong place to ask but I think the issue is bigger than the implementation. I am having trouble finding anything online in either json api or json api resources.

Our situation is that we have table A, table B, and a psuedo join table C (having C.a_id and C.b_id). C also has a number of other fields of information which is why I call it a psuedo join table. So to create a C we can send a POST to example.com/C with the following data:

data: {
  type: 'C',
  attributes:{...},
  relationships: {
    B: {data:{type and id}},
    A: {data:{type and id}}
  }
},

Or we can send a POST to example.com/A/:id/relationships/C with:

data: [{
  type: 'B',
  id: B.id
}]

The first option works fine but there is an internal request that the second is the proper way to do it. The second option, at least as far as I can tell, does not allow you set attributes, is that true? Also as this ‘join’ table will be historical (as in we will want to pull data over time for it), we need to create new entries every time. Currently Im getting an error ‘Relation exists’ when I try the second method, not sure if that is json api or the resources gem we are using. Is there a way around that? What would be the proper recommended way to save these values?

Thanks for your time,
Carl

0 Likes

#2

What happens if you fetch A or B? Do you get relationships to the other, or to C?

I you want to use example.com/A/:id/relationships/C, you should also set C resources as relationship there.

Maybe a middle way would be, stating you want to connect A1 to B1, first calling POST example.com/C with:

{
	"type": "C",
	"attributes": {
		"other": "information"
	},
	"relationships": {
		B: {"type": "B", "id": "1"}
	}
}

Would give a response like:

{
	"data": {
		"type": "C",
		"id": 1,
		"attributes": {
			"other": "information"
		},
		"relationships": {
			"B": {"type": "B", "id": "1"}
		}
	}
}

And then you could call POST example.com/A/1/relationships/C with:

{
	"data": {"type": "C", "id": "1"}
}

This last call would connect A1 to C1. Thus a GET example.com/C/1 would give:

{
	"data": {
		"type": "C",
		"id": 1,
		"attributes": {
			"other": "information"
		},
		"relationships": {
			"B": {"type": "B", "id": "1"},
			"A": {"type": "A", "id": "1"}
		}
	}
}

This does require of course that a C resource can be created without a relation in both directions.


This is just going along with your ideas. I would however use the first option you mentioned as it is way easier.

0 Likes

#3

Thank you for the response, I think we are going to go with the easy route. Your post was helpful and informative though!

0 Likes

#4

This is a common mistake. You should not design your JSON:API as a simple wrapper around your SQL database.

To help us help you, can you tell us what A, B, and C actually are? Or similar alternatives?

0 Likes