Inserting data in vuex-orm database that is already normalized - vue.js

Assuming the data i receive is already normalized, or at least the relations.
How can this data be inserted into the vuex-orm database?
Example JSON data:
{
"carmodel": [
{
"id": 1,
"title": "M3",
"manufacturer_id": 1
},
{
"id": 2,
"title": "a-class"
"manufacturer_id": 2
}
],
"manufacturer": [
{
"id": 1,
"title": "BMW"
},
{
"id": 2,
"title": "Mercedes"
}
]
}
Manufacturer Model and Carmodel are inserted like this:
Manufacturer.insert({ data: response.data.manufacturer })
CarModel.insert({ data: response.data.carmodel })
This example model will not work:
import { Model } from '#vuex-orm/core'
import Manufacturer from '#/models/Manufacturer'
export default class CarModel extends Model {
static entity = 'carModels'
static fields () {
return {
id: this.attr(null),
title: this.string(''),
manufacturer: this.hasOne(Manufacturer, 'manufacturer_id')
}
}
}

Ok, i think i got it. Instead of this.hasOne i have to use belongsTo and use the manufacturer_id from the same model:
import { Model } from '#vuex-orm/core'
import Manufacturer from '#/models/Manufacturer'
export default class CarModel extends Model {
static entity = 'carModels'
static fields () {
return {
id: this.attr(null),
title: this.string(''),
manufacturer_id: this.attr(null),
manufacturer: this.belongsTo(Manufacturer, 'manufacturer_id')
}
}
}

Related

Nest JS - Serialization not work with nested object

I want to append a new field called logo_img_url after data manipulation. It works with the object but the nested array object seems not to work. Any recommendations or solution
import { Expose } from 'class-transformer';
import {} from 'class-validator';
import { Entity, Column } from 'typeorm';
import { BaseEntity } from '#common/base/entity.base';
import { getAdminImageUrl } from '#common/util/vault-file.util';
#Entity()
export class Agency extends BaseEntity {
#Expose()
#Column({
type: 'varchar',
length: '255',
nullable: true,
})
public logo_key!: string;
#Expose({ name: 'logoImgUrl' })
logo_img_url = this.logoImgUrl;
#Expose()
get logoImgUrl(): any {
return "http://localhost:30001/". this.logo_key;
}
}
Actaul response:
{
"data": [
{
"logo_img_url": "",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
Expected result:
{
"data": [
{
"logo_img_url": "http://localhost:3000/9597e74d-aaea-4502-b5cd-b2867504fd80",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "http://localhost:3000/0a655497-1318-4276-a21f-cfdc259241a2",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
You can use #AfterLoad decorator from typeorm. Its calls the decorated method once the entity is loaded and then one can perform the required manipulations.
logo_img_url:string
#AfterLoad()
async transform(){
this.logo_img_url=`http://localhost:30001/${this.logo_key}`
}

how to select value if key is uuid in mongodb

the mongodb data like this:
{
"_id": "123dsadasfa454sdsaw",
"hashmap": {
"uuid-12sadsadw5": {
"name": "bob"
},
"uuid-12sadsadwew5": {
"name": "alice"
}
},
"age": 10
}
"hashmap" like java HashMap, the key is uuid like "uuid-12sadsadwew5" and the value is object.
I want to get the data which the name in "hashmap" value is not null. And I use sql :
db.tabl1.find({"hashmap.values.name":{$ne:null}})
but cannot get the right result
You can use this aggregation query:
First use $objectToArray to create an array with values k and v. As we don't know the key (k) we can search by value (v).
Then $unwind array
And $match values where name is not null.
And then regroup and recreate the object using $arrayToObject.
db.collection.aggregate([
{
"$set": {
"hashmap": {
"$objectToArray": "$hashmap"
}
}
},
{
"$unwind": "$hashmap"
},
{
"$match": {
"hashmap.v.name": {
"$ne": null
}
}
},
{
"$group": {
"_id": "$_id",
"hashmap": {
"$push": "$hashmap"
}
}
},
{
"$set": {
"hashmap": {
"$arrayToObject": "$hashmap"
}
}
}
])
Example here

How to returning only as string column in json response object from eloquent relationship using eager loading

I'm trying to figure out how to eager load data as a string instead of array object from a related table.
I have 3 models and here are the relations
Product.php
class Product extends Model
{
public function ProductTag()
{
return $this->hasMany(ProductTag::class);
}
public function Category()
{
return $this->belongsTo(Category::class);
}
}
ProductTag.php
class ProductTag extends Model
{
public function Product()
{
return $this->belongsTo(Product::class);
}
}
Category.php
class Category extends Model
{
public function Product()
{
return $this->hasMany(Product::class);
}
}
I've tried doing it like so:
public function tag(){
return $this->hasMany(ProductTag::class)
->selectRaw('GROUP_CONCAT(tag) as tag,id')
->groupBy('id');
}
public static function list(){
$result = Category::with(['Product'=>function($q){
$q->with(['tag'=>function($q1){
$q1->first();
}]);
}])->get();
}
Here is the reponse:
{
"data": {
"categories": [
{
"id": 1,
"category": "test 1",
"product": [
{
"id": 46,
"name": "test prod 1",
"tag": []
},
{...}
]
},
{
"id": 2,
"category": "test 2",
"product": [
{
"id": 45,
"name": "test prod 2",
"tag": [
{
"product_tag": "Test1, test12, test123"
}
]
},
{...}
]
},
{
"id": 3,
"category": "test 3",
"product": []
}
]
}
}
The Response is as expected except tag array so, instead of an array named "tag" can I get "product_tag" within the "product" array
"product": [
{
"id": 45,
"name": "test prod 2",
"tag": [
{
"product_tag": "Test1, test12, test123"
}
]
}
]
Here is what I want it to look like:
"product": [
{
"id": 45,
"name": "test prod 2",
"product_tag": "Test1, test12, test123"
}
]
Is it possible and any smart way of doing this in Laravel using Eloquent?
Simple :)
Btw, if you can - rename product_tag in response to tag_line or same - it's not right way to take same name for relation and mutator.
class Product extends Model
{
public function getTagLineAttribute()
{
//tag - is "name" field in ProductTag
return $this->ProductTag->pluck('tag')->implode(',');
}
public function ProductTag()
{
return $this->hasMany(ProductTag::class);
}
public function Category()
{
return $this->belongsTo(Category::class);
}
}
//eager loading with tags
Product::with('ProductTag')->find(..)->tagLine;

Loading `belongsToMany` relation using the `with` method always returning an empty array

I have 2 models, Person and PersonType with a belongsToMany relation.
The problem is that when I try to get all the PersonTypes related to a Person using the query().with() method, it is always returning an empty array even if I have the right data in the 3 tables people, person_type and the intermdiate person_person_type.
This is the code that is trying to load the people with their types:
const Person = use('App/Models/Person')
const people = await Person.query().with('types')
This is what I got from the code above:
[
{
"id": 3,
"firstName": "Eleandro",
"lastName": "Duzentos",
"types": []
},
{
"id": 5,
"firstName": "Lorem",
"lastName": "Ipsum",
"types": []
}
]
This is what it should return:
[
{
"id": 3,
"firstName": "Eleandro",
"lastName": "Duzentos",
"types": [
{
name: "Requester",
slug: "requester"
},
{
"name": "Provider",
"slug": "provider"
},
]
},
{
"id": 5,
"firstName": "Lorem",
"lastName": "Ipsum",
"types": [
{
"name": "Requester",
"slug": "requester"
}
]
}
]
Bellow is each models and their database migrations:
Person:
'use strict'
const Model = use('Model')
class Person extends Model {
static get table () {
return 'people'
}
types() {
return this.belongsToMany('App/Models/PersonType')
.withTimestamps()
}
}
module.exports = Person
'use strict'
/** #type {import('#adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')
class CreatePeopleSchema extends Schema {
up () {
this.create('people', (table) => {
table.increments()
table.string('first_name')
table.string('last_name')
table.date('birth_date')
table.string('address')
table.string('identification_number').nullable()
table.integer('naturality_id').unsigned().index()
table
.foreign('naturality_id')
.references('id')
.inTable('municipalities')
.onDelete('cascade')
table.integer('person_genre_id').unsigned().index()
table
.foreign('person_genre_id')
.references('id')
.inTable('person_genres')
.onDelete('cascade')
table.boolean('is_activated').default(false).notNullable()
table.timestamps()
table.timestamp('deleted_at').nullable()
})
}
down () {
this.drop('people')
}
}
module.exports = CreatePeopleSchema
PersonType:
'use strict'
const Model = use('Model')
class PersonType extends Model {
people() {
return this.belongsToMany('App/Models/Person')
.withTimestamps()
}
}
module.exports = PersonType
'use strict'
/** #type {import('#adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')
class CreatePersonTypesSchema extends Schema {
up() {
this.create('person_types', (table) => {
table.increments()
table.string('name').unique()
table.string('slug').unique().index()
table.text('description').nullable()
table.string('icon').nullable()
table.timestamps()
})
}
down() {
this.drop('person_types')
}
}
module.exports = CreatePersonTypesSchema
and the intermediate table:
'use strict'
/** #type {import('#adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')
class PersonPersonTypeSchema extends Schema {
up () {
this.create('person_person_type', (table) => {
table.increments()
table.integer('person_id').unsigned().index()
table
.foreign('person_id')
.references('id')
.inTable('people')
.onDelete('cascade')
table.integer('person_type_id').unsigned().index()
table
.foreign('person_type_id')
.references('id')
.inTable('person_types')
.onDelete('cascade')
table.timestamps()
})
}
down () {
this.drop('person_person_type')
}
}
module.exports = PersonPersonTypeSchema
This is the query Ludic is performing:
select `person_types`.*, `person_person_type`.`person_type_id` as `pivot_person_type_id`, `person_person_type`.`person_id` as `pivot_person_id` from `person_types` inner join `person_person_type` on `person_types`.`id` = `person_person_type`.`person_type_id` where `person_person_type`.`person_id` in (?, ?)
What I'm doing wrong?
Using pivot table name in association method and handle response format using toJSON()
'use strict'
const Model = use('Model')
class Person extends Model {
static get table () {
return 'people'
}
types() {
return this.belongsToMany('App/Models/PersonType')
.pivotTable('person_type')
}
}
module.exports = Person
I found the issue.
Since I was using the knexSnakeCaseMappers from Objection.js as suggested here, it was making Adonis unable to perform some operations like load relations.
Just remove it and use snake_case or try another solution.

Vue Draggable - Multiple Lists

I want to create something like a trello board where there are multiple columns and I can drag+drop items across different lists. I want to be able to create the columns dynamically since each user will have different number of lists. For vue-draggable, how can I dynamically create computed values for each list?
My data is in this format (which is a single array of lists):
lists:
[
{
"id":1,
"label":"List1"
"items":[
{ "id": 1, "description: "item1" },
{ "id": 2, "description: "item2" },
]
},
{
"id":2,
"label":"List2",
"items":[
{ "id": 3, "description: "item3" },
]
},
{ ... },
{ ... }
]
But I need computed values for each list so I can drag/drop:
computed: {
list1: {
get() {
return this.list1.items
},
set(value) {
this.list1.items
}
},
list2: {
get() {
return this.list2.items
},
set(value) {
this.list2.items
}
}
}
Is there another approach for this scenario?