I have a form where clients can register for contests. They submit their name and email address, and the registration gets stored in a table in the database which has a composite primary key of the contestId and the clientId.
If someone submits the form a second time (i.e., tries to register for the same contest a second time), Prisma throws a failed constraint error. That's fine, and even expected, but I'd like to return the existing entry, and am having a hard time constructing the query.
Schema:
model Client {
id Int #id #default(autoincrement())
email String #unique
first String?
last String?
registrations Registration[]
}
model Contest {
id Int #id #default(autoincrement())
name String #unique
registrations Registration[]
}
model Registration {
contest Contest #relation(fields: [contestId], references: [id])
contestId Int
contestant Client #relation(fields: [clientId], references: [id])
clientId Int
points Int
##id ([contestId, clientId])
}
Registration:
try {
const registration = await prisma.registration.create({
data: {
points: 1,
contest: {
connectOrCreate: {
where: {
name: contest,
},
create: {
name: contest,
}
}
},
contestant: {
connectOrCreate: {
where: {
email: email,
},
create: {
first: first,
last: last,
email: email,
},
},
},
}
});
return res.status(201).send({ ...registration});
}
For new registrants that works, but if the registration already exists, I end up in the catch block. I assume this is the right way to do this — as opposed to, say, querying for existence first, because that seems expensive given that it's likely to be very rare that someone accidentally tries to re-register — but if this isn't a best practice on how to handle things, I'm open to other suggestions.
In the catch block, I then need to find the existing entry, but neither of the two things I've tried have worked:
catch (error) {
// entry already exists
if ('P2002' === error.code) {
const registration = await prisma.registration.findUnique({
where: {
contest: {
is: {
name: contest,
},
},
contestant: {
is: {
email: email,
},
},
},
})
return res.status(200).send(...registration);
}
return res.status(500).end(`Register for contest errorr: ${error.message}`);
}
complains Argument where of type RegistrationWhereUniqueInput needs exactly one argument, but you provided contest and contestant.
And
const registration = await prisma.registration.findUnique({
where: {
contestId_clientId: {
contest: {
is: {
name: contest,
},
},
contestant: {
is: {
email: email,
},
},
},
},
})
complains
Unknown arg `contest` in where.contestId_clientId.contest for type RegistrationContestIdClientIdCompoundUniqueInput. Did you mean `contestId`?
Unknown arg `contestant` in where.contestId_clientId.contestant for type RegistrationContestIdClientIdCompoundUniqueInput. Did you mean `contestId`?
Argument contestId for where.contestId_clientId.contestId is missing.
Argument clientId for where.contestId_clientId.clientId is missing.
I feel like this latter approach of using Prisma's auto-generated contestId_clientId is directionally right, but how do I construct the Prisma query to find it, starting from having the contest name and client email?
Instead of finding a unique record from the registration model, you can do a query something like this to find the Contest and Client details. The only valid argument for findUnique in the registration model would be: contestId_clientId and you can only pass contestId and clientId in them, other values are not allowed.
const registration = await prisma.client.findUnique({
where: {
email: 'email',
},
include: {
registrations: {
select: {
contest: contest,
points: true,
},
},
},
});
I want to query a many-to-many relation in prisma, like "select all posts where the category ID equals 'abc...' ".
This seems fairly simple but even after spending 2 hours reading the Prisma docs on relational queries, I can't figure it out.
model Category {
id String #id #default(cuid())
name String
post Post[]
}
model Post {
id String #id #default(cuid())
body String
category Category[]
}
const posts = await prisma.post.findMany({
select: {
category: {
where: {id: "abc123"}
}},
});
this returns an array of as many category objects as there are posts.
This will return all posts which have the category of id abc123. Note that posts may include categories other than id abc123.
const posts = await prisma.post.findMany({
where: {
category: {
some: {
id: 'abc123',
},
},
},
});
some: Returns all records where one or more ("some") related records match filtering criteria.
https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#some
What I would like to do is to get specific data from Status for a group of 10-40 GitHub users from the organization. I would like to get the data in one batch. Currently, my solution queries the data using for loop in the code and a query below:
{
user(login: "user1") {
status {
indicatesLimitedAvailability
updatedAt
createdAt
}
The disadvantage of this solution is I have to use sleep not to trigger API calls per minute limit in GitHub.
Would it be possible to transform the query to something like this (pseudocode):
{
user(login: "user1", "user2", "user3", ...) {
status {
indicatesLimitedAvailability
updatedAt
createdAt
}
And some kind of list in the response?
You can use the following query:
{
nodes(ids: ["node_id1", "node_id2"]) {
... on User {
status {
indicatesLimitedAvailability
updatedAt
createdAt
}
}
}
}
Where node_id is the id of the users you want to query for.
You can obtain these using the following query:
{
user(login: "username") {
id
}
}
Or you could get all members in an organisation with the following query
{
organization(login: "org_name") {
membersWithRole(first: 100) {
nodes {
login
id
}
}
}
}
I have two collections in db,
1. products (product_id, name, status, price, unit_price)
2. cart_details (cart_id, product_id, quantity)
Problem I am facing is, I want to show descriptive record on cart details page from these both collections. Where unit_price and product_name will come from products collection while quantity will be used from cart_details collection. I referred Mongo DB's own documentation it do returns me collection with nested objects but problem with that is if i want to update quantity in cart_details collection it throw an exception of "type mismatch".
Don't know if there is any other way to join tables and on update of one collection it won't throw any error.
here is the update cart code.
exports.update = function(req, res) {
var cart = req.cart;
cart = _.extend(cart, req.body);
cart.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(cart);
}
});
};
and here is the cart service:
angular.module('core').factory('Cart', ['$resource',
function($resource) {
return $resource('cart/:cartId', { cartId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]);
How get a user of this class, from a lastName, not from the id.
in my example i use a REST web service.
My class USER.groovy in Grails:
class User {
String firstName
String lastName
String zipcode }
class UrlMappings.groovy
class UrlMappings {
static mappings = {
/user/$id" (controller: "user") {
action = [GET: "show"]
}
}
}
def show in UserController.groovy
def show = {
User user = User.get(params.id)
if (user) {
render user as JSON
} else {
SendNotFoundResponse()
}
}
As I understand, your problem that you don't know how to query domain by other fields that id. For current example you can use:
User.findByFirstName(params.id)
And, please read about GORM querying - http://grails.org/doc/latest/guide/GORM.html#querying