Skip to main content

Host hasMany places through HostPlace Place hasMany hosts through HostPlace

Git Log

commit 27245163c9afdc0c55bc0c2e47399fdc894976ec
Author: Daniel Nelson <844258+daniel-nelson@users.noreply.github.com>
Date: Sat Nov 8 10:55:05 2025 -0600

Host hasMany places through HostPlace
Place hasMany hosts through HostPlace

Association types synced
Model specs

To run migration:

```console
yarn psy db:migrate

If you changed a migration that you already ran (only before the feature has been merged into main...once a migration has been run on a server, it must not be changed or removed; instead, create a new migration with yarn psy g:migration ...), either:

yarn psy db:rollback
yarn psy db:migrate

or

yarn psy db:reset

After adding HasMany/HasOne/BelongsTo associations:

yarn psy sync
// yarn psy db:migrate will also sync

To run model unit specs:

yarn uspec spec/unit/models

## Diff from 8b8489d

```diff
diff --git a/api/spec/unit/models/Host.spec.ts b/api/spec/unit/models/Host.spec.ts
index 9255d5c..ef54e54 100644
--- a/api/spec/unit/models/Host.spec.ts
+++ b/api/spec/unit/models/Host.spec.ts
@@ -1,3 +1,13 @@
+import createHost from '@spec/factories/HostFactory.js'
+import createHostPlace from '@spec/factories/HostPlaceFactory.js'
+import createPlace from '@spec/factories/PlaceFactory.js'
+
describe('Host', () => {
- it.todo('add a test here to get started building Host')
+ it('has many Places (through hostPlaces)', async () => {
+ const host = await createHost()
+ const place = await createPlace()
+ await createHostPlace({ host, place })
+
+ expect(await host.associationQuery('places').all()).toMatchDreamModels([place])
+ })
})
diff --git a/api/spec/unit/models/Place.spec.ts b/api/spec/unit/models/Place.spec.ts
index 10bcdd9..6315065 100644
--- a/api/spec/unit/models/Place.spec.ts
+++ b/api/spec/unit/models/Place.spec.ts
@@ -1,3 +1,13 @@
+import createHost from '@spec/factories/HostFactory.js'
+import createHostPlace from '@spec/factories/HostPlaceFactory.js'
+import createPlace from '@spec/factories/PlaceFactory.js'
+
describe('Place', () => {
- it.todo('add a test here to get started building Place')
+ it('has many Hosts (through hostPlaces)', async () => {
+ const host = await createHost()
+ const place = await createPlace()
+ await createHostPlace({ host, place })
+
+ expect(await place.associationQuery('hosts').all()).toMatchDreamModels([host])
+ })
})
diff --git a/api/src/app/models/Host.ts b/api/src/app/models/Host.ts
index 8536e0d..b5e8782 100644
--- a/api/src/app/models/Host.ts
+++ b/api/src/app/models/Host.ts
@@ -1,7 +1,9 @@
-import { Decorators } from '@rvoh/dream'
-import { DreamColumn, DreamSerializers } from '@rvoh/dream/types'
import ApplicationModel from '@models/ApplicationModel.js'
+import HostPlace from '@models/HostPlace.js'
+import Place from '@models/Place.js'
import User from '@models/User.js'
+import { Decorators } from '@rvoh/dream'
+import { DreamColumn, DreamSerializers } from '@rvoh/dream/types'

const deco = new Decorators<typeof Host>()

@@ -24,4 +26,10 @@ export default class Host extends ApplicationModel {
@deco.BelongsTo('User', { on: 'userId' })
public user: User
public userId: DreamColumn<Host, 'userId'>
+
+ @deco.HasMany('HostPlace')
+ public hostPlaces: HostPlace[]
+
+ @deco.HasMany('Place', { through: 'hostPlaces' })
+ public places: Place[]
}
diff --git a/api/src/app/models/Place.ts b/api/src/app/models/Place.ts
index ee1bcf4..9f8b47d 100644
--- a/api/src/app/models/Place.ts
+++ b/api/src/app/models/Place.ts
@@ -1,6 +1,8 @@
+import ApplicationModel from '@models/ApplicationModel.js'
+import Host from '@models/Host.js'
+import HostPlace from '@models/HostPlace.js'
import { Decorators } from '@rvoh/dream'
import { DreamColumn, DreamSerializers } from '@rvoh/dream/types'
-import ApplicationModel from '@models/ApplicationModel.js'

const deco = new Decorators<typeof Place>()

@@ -23,4 +25,10 @@ export default class Place extends ApplicationModel {
public deletedAt: DreamColumn<Place, 'deletedAt'>
public createdAt: DreamColumn<Place, 'createdAt'>
public updatedAt: DreamColumn<Place, 'updatedAt'>
+
+ @deco.HasMany('HostPlace', { dependent: 'destroy' })
+ public hostPlaces: HostPlace[]
+
+ @deco.HasMany('Host', { through: 'hostPlaces' })
+ public hosts: Host[]
}