Including One-To-One association from both sides - node.js

I have two models that need to be connected in a one-to-one association: Coach and Team. A team only has one coach and a coach only has one team.
I need to be able to include from both sides: sometimes I query the Coach and include the Team, sometimes I query the Team and include the Coach.
Now I'm not sure: do I need to create reference columns on each table (CoachId in table "Teams" and TeamId in table "Coaches")?
I have tried creating those two columns and established the association like so:
module.exports = models => {
models.Coach.hasOne(models.Team)
models.Team.belongsTo(models.Coach)
}
But for some reason, when I'm creating a Coach and setting the existing TeamId, the TeamId column stays empty. Also, even if it would have been filled, it feels odd to also have to update the Coach row with the correct TeamId.
Can it all be accomplished in one write and then be queried from both sides as suggested above? Feels like I still have not understood something fundamental about Sequelize, even after working with it for a while.
Thanks!

to query from both sides, you need to use a through table
module.exports = models => {
models.Coach.hasOne(models.Team)
models.Team.belongsTo(models.Coach, {through: 'TeamCoach'})
}
TeamCoach will have primary keys from both tables linked such that it can allow for a bi directional query.

Related

should i deal with ID's or with models

i am using sequelize and when i want to set products for an order (M2M Relation)
i must put all the product object not only the id
EX:
Order.setProducts([1,2,3]) // dont work
Order.setProducts([{name: "1",price: 1},{name: "2",price: 2}]) // work
so i was wondering is that good for performance
and should i always deal with whole object or i should deal only with the ID's and after getting the ID's i do this ..
Product.findById(id)
for each productid i have
SetProducts is a function add to an sequelize instance because of your associations in the model. So calling it with the ids dont work, because your are writing the ids directly in your product table. If you want to push only the ids. Which at the the end is a better structure, you need an addiontal table, where your store id of the order and ids of the products.
In your case, in your posted question above, you are adding, the product details each time you create an order.

Using modifier with Objection.js relationmapping

I have four tables vehicle_parts, part_pricing, labour_pricing and paint_pricing. Vehicle_parts table is having one to many relationship with remaining tables. Each table is having a field is_active indicating whether record is active or not. So ideally for every part in vehicle_parts table there will be only one active price in part_pricing.
I am using Objection.js to build my model as shown below -
I have a function where i am querying the vehicle part model to fetch vehicle parts along with associated prices, as shown below -
I am using withGraphFetched() method to get relational data and i am getting that.
The problem i am facing is when i am getting vehicle parts, i am getting active parts only, however i am getting non-active prices as well along with active price in relational data.
I know this can be solved using modifiers but i am not sure how to use that. In simple words i need to check is_Active flag in every relation when fetching data using withGraphFetched().
Thanks for sharing your wisdom.
You should apply filters in the model when setting up the relationship.
Like,
for example,
part_pricing: {
relation: BaseModel.HasManyRelation,
modelClass: path.join(__dirname, '/PartPricing'),
filter: (builder) => builder.where('is_active', true),
join: {
from: 'vehicle_parts.id',
to: 'part_pricing.vehicle_part_id',
},
}

Creating associations of a tables that both have composite keys

I have a problems in sequelize to create a relationship between to models that both have composite keys. Let me show you the tables.
Usually to create a relationship between to models in sequelize, we use belongsTo or hasMany etc, and then set the foreignKey to the primaryKey of the target table (e.g. toolsName || tools_name). In my case I need to create a relationship of historyTool that belongsTo tools, so the code will look like this.
models.ChecklistTool.belongsTo(models.Tools, {
foreignKey: 'toolsName',
as: 'Tools'
}
);
Now, the problem is table tools set the clusterId as its another primaryKey which resulting a composite primary key for table (e.g. (glasses)(1)), I'm confused how to create the associate models.
While I realize it will be much easier if table tools has its own auto increment id (tools_id), it will be much help if I know how to create one without it, since it will be a good references in the future when I don't have any control in designing the tables.
Thank you so much, any help will be appreciated.
I just write it in SQL, use sequelize.query() method and get along with it.

How do i implement friendship functionality in database using sequelize for social media demo app

I'm building a social media demo app and to add friends functionality to that app.
In database I am thinking about making new table(model in sequelize) which contains user1 id and user2 id and a status with one character (accepted, rejected etc).
I tried implementing it but faced some issue: Now i need to have unique key but for combination of user 1 and user 2 (pair of user1 and user2 id).
How do I implement something like this using sequelize and also I don't think this is the best way to do it, so if you have a better way please let me know, thanks.
Your description is somewhat lacking and missing some components. However it is clear enough to see what you are describing
is a many-to-many (m:m) relationship. It is just that the both sides come from the same table. While not the most common relationship,
neither is it too unusual. Further the resolution is the same as any other m:m. Create another table that has the key to both sides
as foreign keys. There is one slightly unusual twist in that the combination (parent1, parent2)(P1,P2) and the combination (P2,P1)
should be considered the same. This introduces a slight twist to the norm; instead of generating a PK from the the parent columns
the PK will be just be sequence generated (technically the PK is not required unless there are anticipated child tables of it).
We then create a unique index on the ordered pair (P1,P2). So something along the line of:
create table friends( f_id integer generated always as identity
, user_id_1 integer not null
, user_id_2 integer not null
, status varchar(1) not null default 'P'
, friends_since date not null default now()::date
, constraint friends_pk primary key(f_id)
, constraint f2user_1_fk foreign key(user_id_1)
references users(user_id)
, constraint f2user_2_fk foreign key(user_id_2)
references users(user_id)
, constraint cannot_friend_self
check (user_id_1 != user_id_2)
);
--
-- unique index to recognize (P1,P2) = (P2,P1)
create unique index already_friends on friends
( least(user_id_1,user_id_2), greatest(user_id_1,user_id_2) );
See fiddle here for examples. The bi-directional nature of Friends table causes additional complications within the queries. Typically I hide complication within SQL functions. I have also added a couple useful functions. You should be able to uses these as examples. Note, since they are SQL functions you can extract the statement and convert to a parameterized query.
Sorry, I do not know sequelize so I will not guess at the translation, but there seem to be many examples of the internet for all the above.

Can I create a unique constraint on Loopback4's hasManyThrough (M:M) table

Preamble
I'm somewhat new to Loopback 4, and I have successfully created 2 working CRUD controllers, repositories, models, etc. I have Users and Organizations, and I am have successfully created a M:M relation between Users and Organizations using the relation generator. So, I can create a user, create an organization, and separately I can link them together in a many-to-many table called "membership". All of this follows (as far as I know) loopback best practices per their docs.
Question:
How do I make sure that each record in the membership table is unique?
here's an example of my table with duplicates
For example, User #1, Jeff, joins Organization #1, Amazon. Some erroneous code then attempts to add Jeff to Amazon a 2nd time, I want this to fail.
I was thinking I could simply check the database if the record exists, but it seems cleaner to add this constraint to the model, so that any attempted insert would fail if duplicate. I have dug around in the docs and haven't found anything.
Any help is appreciated!
In database design, a unique constraint would be enforced by a compound/composite key on the junction table. This would enforce a unique pair of orgId and userId.
Hence, the junction table should have only 2 columns:
orgId
userId
To create a composite key in LoopBack 4, update the through model as follows:
// Some parts were omitted for bevity
#model()
export class OrgUser extends Entity {
#property({id: 1})
orgId: number;
#property({id: 2})
userId: number;
constructor(data?: Partial<OrgUser>) {
super(data);
}
}

Resources