does anyone know how to retrieve all the data including from the relationship in AdonisJS ? ,
so I want to retrieve the user data from the User Model including the relationship data in the Post Model.
get All users
public async getUsers({ response }: HttpContextContract) {
try {
const data = await User.all()
return response.status(200).send({ "result": data })
} catch(err) {
return response.status(400).json({ error: err.message })
}
}
First, you will need to define the relationships on your model.
A User has many Posts:
export default class User extends BaseModel {
...
#hasMany(() => Post) // 👈 One-to-many relationship
public posts: HasMany<typeof Post>
}
A Post belongs to a User:
export default class Posts extends BaseModel {
...
#belongsTo(() => User) // 👈 a Post belongs to a User
public user: BelongsTo<typeof User>
}
Now, in your query, you can preload the relationship.
const users = await User
.query()
.preload('posts')
First:
You can use belongsTo in User model to make relationship data with Post model
post_model() {
return this.belongsTo("App/Models/Post")
}
Second:
Call the model use query like this:
await User.query()
.with("post_model", builder => {
builder.select("id", "name", "post")
})
Related
I have trouble dealing with populating the field using TypeGraphQL.
Situation summary with an example:
TypeGraphQL
TypeDef
#ObjectType()
class User {
...
}
#ObjectType()
class Post {
...
#Field()
user: User
}
Resolver
import { Post, User } from '#/models' // mongoose schema
#Resolver(() => Post)
class PostResolver {
#Query(() =>. Post)
async getPost(id: string) {
return await Post.findById(id);
}
...
#FieldReoslver(() => User)
async user(#Root() post: Post) {
return await User.findById(post.user) // Error Occurs here.
}
}
Mongoose
PostSchema
const PostSchema = new Schema({
...
user: {
type: Schema.ObjectId,
ref: "User",
}
})
I want to populate user field when the data Post is requested, with the field User type.
So, I used #FieldResolverlike above, but I encountered the Type Error because post.user is a type of User, not ObjectId of mongoose.
The user field is a type of ObjectId first when the getPost resolver was executed, but I want to populate this field to User when the client gets the response.
How can I get through this?
Thanks in advance.
I want to get data from table relation in Adonisjs. I using .with function to get data from table relation but just for some column, but it doesn't work.
My controller code like this:
const cart = await Shop.query()
.with('products',(builder)=>{
builder.select('id','product_name')
})
.select('id_shop')
.fetch()
return response.json({
status:true,
message: false,
data: cart
})
But the result of code above is only id_shop, like this:
[
{
'id_shop': '1'
'products': []
},
{
'id_shop': '2'
'products': []
}
]
edited
I added my shop's model here:
class Shop extends Model {
static get table()
{
return 'shop'
}
static get primaryKey()
{
return 'id_shop'
}
products ()
{
return this.hasMany('App/Models/Product','id_shop', 'shop_id')
}
}
And my product's model:
class Product extends Model {
static get table()
{
return 'product'
}
static get primaryKey()
{
return 'id_product'
}
}
Whats wrong with my code?
you put wrong hasMany relation in Model
hasMany relationship like this
products ()
{
return this.hasMany('App/Models/Product','shop_id', 'id_shop')
}
or change in controller where you use builder change like this
const cart = await Shop.query()
.with('products',(builder)=>{
builder.select('id_product','product_name')
})
.select('id_shop')
.fetch()
change you id to id_product
you can try this
I have two tables:
#Entity('Reviews')
class Review {
...
#OneToMany((type) => MapCategory, map => map.review)
public categories: MapCategory[];
}
And:
#Entity('MapCategories')
export class MapCategory {
...
#ManyToOne(type => Review, (review) => review.categories)
public review: Review;
}
When I try the filter on 'categories' but the result doesn't filter 'categories' following the key that I already push.
const items = await this.reviewRepository.findAndCount({
relations: ['categories'],
where: {
categories: {
id: 1
}
}
});
We need to use queryBuilder for cases like this since find doesn't allow filtering relations:
const items = await reviewRepository.createQueryBuilder("review")
.leftJoinAndSelect("review.categories", "category")
.where("category.id = :id", { id })
.getManyAndCount()
I prefer to avoid query builder when possible.
There's a workaround for filtering based on relation fields for findOne()/find() methods that I've discovered recently. The problem with filtering related table fields only exists for ObjectLiteral-style where, while string conditions work perfectly.
Assume that we have two entities – User and Role, user belongs to one role, role has many users:
#Entity()
export class User {
name: string;
#ManyToOne(() => Role, role => role.users)
role: Role;
}
#Entity()
export class Role {
#OneToMany(() => User, user => user.role)
users: User[];
}
Now we can call findOne()/find() methods of EntityManager or repository:
roleRepository.find({
join: { alias: 'roles', innerJoin: { users: 'roles.users' } },
where: qb => {
qb.where({ // Filter Role fields
a: 1,
b: 2
}).andWhere('users.name = :userName', { userName: 'John Doe' }); // Filter related field
}
});
You can omit the join part if you've marked your relation as an eager one.
There is the description how to do this in typeorm official docs https://typeorm.io/#/many-to-one-one-to-many-relations. But I can't do the same in NestJS with Repository and insert method.
I have written these entities (other columns were omitted)
#Entity()
export class News {
#OneToMany(type => NewsImage, image => image.news)
public images: NewsImage[];
}
#Entity()
export class NewsImage {
#ManyToOne(type => News, news => news.images)
public news: News;
}
I have tried something like this
function first() {
const news = new News();
const image = new NewsImage();
news.images = [ image ];
return from(this.newsRepo.insert(news))
.pipe(
switchMap(() => this.imageRepo.insert(image)),
);
}
function second() {
const news = new News();
const image = new NewsImage();
image.news = news;
return from(this.imageRepo.insert(image))
.pipe(
switchMap(() => this.newsRepo.insert(news)),
)
}
It inserts news and image, but image's newsId is null.
Check cascade property
#Entity()
export class News {
#OneToMany(type => NewsImage, image => image.news, { cascade: ['insert', 'update'] })
public images: NewsImage[];
}
Then if you do something like
let news = {
images: [{
date: "",
etc: ""
}],
title: ""
}
If then you call this.repository.save(news) it will save the news and the images. And updates too. Check more docs about this on typeorm docs.
Declaring new News() creates a new entity but does not save it to the database. You first need to insert or .save() the news object and then add it to image.
async function first() {
// you can .save() it however you want, the point is it must be saved to the db
const news = await News.create({ title: 'Async rules the world' }).save()
const image = new NewsImage()
image.news = news // now news has an id from the database
// ...
}
I am trying to create an association between an existing (user) entity and save the new entity (visit).
I've read the sequelize docs and can't see a better way of doing this than saving the first entity using async/await, then fetching it again passing include as an option. See below.
export const createVisit = async(req, res) => {
req.assert('BusinessId', 'Must pass businessId').notEmpty();
req.assert('UserId', 'Must pass customerId').notEmpty();
const visit = await new Visit({
UserId: req.body.UserId,
BusinessId: req.body.BusinessId,
redemption: false,
})
.save()
.catch((error) => {
res.status(400).send({ error });
});
const visitWithUser = await Visit.findById(visit.id, {include: [{model: User, attributes: ['firstName','lastName','facebook', 'gender','email']}]})
res.status(200).send({ visit: visitWithUser })
};
Is there a way to save the entity and get sequelize to return the saved entity along with any associations?
I think it supports this feature , as per the doc , you can do it like this :
Visit.create({
UserId: req.body.UserId,
BusinessId: req.body.BusinessId,
redemption: false,
}, {
include: [User]
}).then(function(comment) {
console.log(comment.user.id);
});
Here is the git discussion if you want to read.