-
Hi! I have the weird situation where a call to async show ({ params, auth, response, transform }) {
let study
try {
study = await auth.user
.studies()
.where('id', params.id)
.with('jobs.variables.dtype')
.with('participants')
.firstOrFail()
} catch (e) {
return response.notFound({ message: `Study with ID:${params.id} could not be found` })
}
console.log('Data:', study)
console.log('Type:', typeof study)
console.log('Relations:', study.$relations)
return transform
.include('jobs')
.include('participants')
.item(study, 'StudyTransformer') Prints:
If I simply replace the call to Data: Study {
__setters__: [
'$attributes',
'$persisted',
'primaryKeyValue',
// ... ommitted for brevity
'$visible': undefined,
'$hidden': undefined
}
Type: object
Relations: {
jobs: VanillaSerializer {
rows: [ [Job], [Job], [Job], [Job], [Job] ],
pages: null,
isOne: false
},
participants: VanillaSerializer {
rows: [
[Participant],
[Participant],
[Participant],
[Participant],
[Participant]
],
pages: null,
isOne: false
}
} The weird thing is that it only happens in this situation. In all other situations For completeness, here are my user and study models with the defined relationships. class User extends Model {
static boot () {
super.boot()
// ... ommitted for brevity
this.addGlobalScope(function (builder) {
builder.with('userType')
})
}
// .... ommitted for brevity
/**
* A user can have many studies, but a study can also belong to more than one user
* (i.e. a shared study)
*
* @method studies
*
* @return {Object}
*/
studies () {
return this
.belongsToMany('App/Models/Study')
.pivotModel('App/Models/StudyUser')
.withPivot(['is_owner', 'access_permission_id'])
}
}
class Study extends Model {
/**
* The study's owners
*
* @method users
*
* @return {Object}
*/
users () {
return this
.belongsToMany('App/Models/User')
.pivotModel('App/Models/StudyUser')
.withPivot(['is_owner', 'access_permission_id'])
}
/**
* The jobs belonging to this study
*
* @method jobs
*
* @returns {Object}
* @memberof Study
*/
jobs () {
return this.hasMany('App/Models/Job')
}
/**
* The column headers of the job table (i.e. variable names per job)
*
* @method jobFields
*
* @returns {Object}
* @memberof Study
*/
variables () {
return this.hasMany('App/Models/Variable')
}
/**
* Participants of this study
*
* @method participants
*
* @returns {Object}
* @memberof Study
*/
participants () {
return this
.belongsToMany('App/Models/Participant')
.pivotModel('App/Models/Participation')
}
/**
* Walks through the list of jobs specified as a collection of key:value pairs in an object
* and transform them so that they can easily be stored in the
* database. Additionally check if the supplied variable name exists for this study.
*
* @param {Array} jobsData The jobs to transform
* @returns {Array}
* @memberof Study
*/
async saveJobsFromInput (jobsData) {
// Obtain the list of variables that are used for this study.
const variables = await this.variables().pair('name', 'id')
const varsList = Object.keys(variables)
// TODO: this procedure can undoubtedly be optimized by using a database transaction. This allows us
// to create the job at the start of the map() function, and enable us to implement everything
// in a single loop, instead of two.
const jobs = await Promise.all(jobsData.map(async (jobData) => {
// Check if all variables exists for this study
for (const varName of Object.keys(jobData)) {
if (!varsList.includes(varName)) {
throw new Error(`Variable '${varName}' does not exist for this study.`)
}
}
// Create the job
const job = await this.jobs().create({})
// Attach the job to the variables using the specified values
for (const [varName, varValue] of Object.entries(jobData)) {
await job.variables().attach(variables[varName], (row) => { row.value = varValue })
}
return job
}))
return jobs
}
} I appreciate any insights on how to fix this! Edit 1It just occurred to me that it might be helpful if I include some version information of the packages I am using:
Edit 2I can also very easily reproduce this in the REPL: $> adonis repl
> const User = use('App/Models/User')
> const user = await User.find(1)
> await user.studies().where('id', 1).firstOrFail()
{
id: 1,
name: 'Attentional Capture',
description: 'Basic attentional capture experiment',
active: 1,
osexp_path: '/public/osexp/attentional-capture.osexp',
created_at: 2020-07-16T13:53:30.000Z,
updated_at: 2020-07-16T13:53:30.000Z
}
> await user.studies().where('id', 1).first()
Proxy [
Study {
__setters__: [
'$attributes',
'$persisted',
'primaryKeyValue',
'$originalAttributes',
'$relations',
'$sideLoaded',
'$parent',
'$frozen',
'$visible',
'$hidden'
],
'$attributes': {
id: 1,
name: 'Attentional Capture',
description: 'Basic attentional capture experiment',
active: 1,
osexp_path: '/public/osexp/attentional-capture.osexp',
created_at: 2020-07-16T13:53:30.000Z,
updated_at: 2020-07-16T13:53:30.000Z
},
'$persisted': true,
'$originalAttributes': {
id: 1,
name: 'Attentional Capture',
description: 'Basic attentional capture experiment',
active: 1,
osexp_path: '/public/osexp/attentional-capture.osexp',
created_at: 2020-07-16T13:53:30.000Z,
updated_at: 2020-07-16T13:53:30.000Z
},
'$relations': {},
'$sideLoaded': {
pivot_study_id: 1,
pivot_user_id: 1,
pivot_is_owner: 1,
pivot_access_permission_id: 2
},
'$parent': null,
'$frozen': false,
'$visible': undefined,
'$hidden': undefined
},
{ set: [Function (anonymous)], get: [Function (anonymous)] }
] Edit 3My final analysis for now is that this problem only occurs if /* Doesn't work */
const User = use('App/Models/User')
const user = await User.find(1)
const study = await user.studies().where('id', 1).firstOrFail() // returns plain object
/* Works */
const Study = use('App/Models/Study')
const study2 = await Study.query().where('id', 1).firstOrFail() // returns model instance I have tested this for other relations as well, and there this pattern occurs too. If this is a bug, let me know and I will file a bug report. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
It seems to be fixed by upgrading to Lucid v6, but I am really confused which versions of adonis' subpackages are compatible now. I was under the assumption that Lucid v6 or even v5 would only work with Adonis v5, while I am still on v4, but this appears not to be the case. Is it safe to upgrade most internal dependencies of Adonis? |
Beta Was this translation helpful? Give feedback.
It seems to be fixed by upgrading to Lucid v6, but I am really confused which versions of adonis' subpackages are compatible now. I was under the assumption that Lucid v6 or even v5 would only work with Adonis v5, while I am still on v4, but this appears not to be the case. Is it safe to upgrade most internal dependencies of Adonis?