geddy / model

Datastore-agnostic ORM in JavaScript
265 stars 55 forks source link

How do I save data to association models? #244

Closed OscarGodson closed 9 years ago

OscarGodson commented 9 years ago

I have a User model and a Family model that are connected by a FamiliesUser model (using {through: "FamiliesUsers"}) . I'm still new to SQL, but from what I read the FamiliesUser model is where you would store meta data about that relationship. For example, in this case, my families_users table has a permissionsLevel property so we can set permissions per user per family. I'm not really clear how I go about setting or really getting this data.

When I create a user, and it also creates the family and the user/family relationship, I don't get an ID for the created FamiliesUser. Which means to set the value I have to:

  1. Create the user
  2. Get the user and include family
  3. Do a FamiliesUser.first() lookup where I look for the user id that also has the family id
  4. Set my permissionsLevel property
  5. Save

That seems like a lot of work for setting any data in through models. Do you have suggestions or is there an undocumented way of passing data to through models when creating them?

mde commented 9 years ago

You can eager-fetch both the main association and the join-model:

https://github.com/geddy/model/blob/master/test/integration/adapters/sql/eager_assn.js#L71

So your returned User would have both Family and FamiliesUser (I would have used something like Membership or even FamilyMembership that makes sense on its own, but whatever. :)) and you can then update and save whichever of them you want.

OscarGodson commented 9 years ago

Good point on the naming thing. I'll go with FamilyMembership. From an API standpoint that makes a lot more sense for the clients.

So I'm doing these steps:

  1. Create User
  2. Save User
  3. Add Family to returned User
  4. Save User again
  5. Call a User.first() and include FamilyMembership
  6. Make changes to FamilyMembership
  7. Save FamilyMembership

Would be a nice feature to be able to skip the 5th step since we have the association model as well as the User by that point. But you answered my question so I'll close it, thank you! :)

mde commented 9 years ago

You have the associated Family model, but the join-model instance (the FamilyMembership) doesn't exist until you save the association (which happens in step 4). We don't return ids for associated items that get saved in a cascade that way (I don't even know what the API for that would look like), so you have to do a fetch after the save to get the newly created FamilyMembership instance. Hope that helps explain.

OscarGodson commented 9 years ago

I see. Kinda makes it weird since some things should be required in the database (NOT NULL) like permissionsLevel, however, I can't set that until after its created so I need to set all columns and model properties to NULL and required:false and sort of just hope all went well during creation.

mde commented 9 years ago

Oh, that's a very good point -- there's not a nice validation story for the creation of join-model instances, since they're created implicitly. I'm not sure what a good way to handle explicit creation of join-models would be, or if there even is one. Probably the best approach is what you're describing.