I Have 4 RDBMS tables:
Audience { Id, UserName }
AudienceRel { SenderId, ReceiverId, EmailId }
Email { Id, FolderId }
Folder { Id, Path }
I need a teleporter configuration like this:
A relation between Audiences by the AudienceRel table from sender Audience to Receiver audience.
A FileSetId property for new relation which requires joining between AudienceRel and Email table (something like "since" property on this page )
Any suggest?
Best regards...
Related
Using Prisma 3.7.0.
I'm following this example in the docs
model Person {
id Int #id #default(autoincrement())
name String?
followers Follows[] #relation("follower")
following Follows[] #relation("following")
}
model Follows {
follower Person #relation("follower", fields: [followerId], references: [id])
followerId Int
following Person #relation("following", fields: [followingId], references: [id])
followingId Int
##id([followerId, followingId])
}
Then I try creating a User along with the people they're following, with the below code.
const person = await prisma.person.create({
data: {
following: {
create: [
{ following: { connect: { id: 1 } } }
]
}
}
});
I'm getting the following (see what I did there :)) error.
/usr/src/app/node_modules/#prisma/client/runtime/index.js:34755
const error2 = new PrismaClientValidationError(renderErrorStr(validationCallsite));
^
PrismaClientValidationError: Unknown arg `following` in data.following.create.0.following for type FollowsCreateWithoutFollowingInput. Did you mean `follower`?
Argument follower for data.following.create.0.follower is missing.
at Object.validate (/usr/src/app/node_modules/#prisma/client/runtime/index.js:34755:20)
at PrismaClient._executeRequest (/usr/src/app/node_modules/#prisma/client/runtime/index.js:39749:17)
at consumer (/usr/src/app/node_modules/#prisma/client/runtime/index.js:39690:23)
at /usr/src/app/node_modules/#prisma/client/runtime/index.js:39694:49
at AsyncResource.runInAsyncScope (node:async_hooks:199:9)
at PrismaClient._request (/usr/src/app/node_modules/#prisma/client/runtime/index.js:39694:27)
at request (/usr/src/app/node_modules/#prisma/client/runtime/index.js:39799:77)
at _callback (/usr/src/app/node_modules/#prisma/client/runtime/index.js:40007:14)
at PrismaPromise.then (/usr/src/app/node_modules/#prisma/client/runtime/index.js:40014:23) {
clientVersion: '3.7.0'
}
I believe the reason I'm getting this error is because the following[] relation creates an input as mentioned in the error message FollowsCreateWithoutFollowingInput, meaning it's expecting a follower relation and not a following, as the following will be the Person I'm currently creating, and I just need to tell it who is the follower Person.
However this doesn't make sense to me. When I'm creating a Person along with its people they're following, I understand that to be an array of Persons who the person I'm currently creating is following. If so, then a Follows record in the following array contains the current Person (the one I'm creating) as the follower relation and some other Person as the following relation. And the relation I should be inputting is the following and not the follower. Therefore the input type that prisma should generate should be FollowsCreateWithoutFollowerInput instead of FollowsCreateWithoutFollowingInput.
What am I missing, in my understanding?
I looked at the below resources during my research on this.
count self relation on Prisma error: table name specified more than once. This is discussing a different issue, using the same example.
https://github.com/prisma/prisma/discussions/3960. This discusses how to create the same type of relation, where the join table references the same table for both ids. But it doesn't explain how to create records once the relationships are defined.
One-to-many self-relation in prisma schema. This shows how to create a record, but its not using the join tables relation during create it's using a property. Also it's not exactly the same case as the join table seems to be the same table.
`const person = await prisma.person.create({
data: {
following: {
connect: { id: 1 }
}
}
});
It's the "create" in the body of the function that's doing it. The second nested following would also cause a problem if you just fix that though.
Think of it like you aren't creating the follower. The follower already needs to be there. You are just creating a record of the connection between the person and the follower. So prisma.person.create some data that this person has a follower and that follower is connected to the user with id whatever.
I have an app where I need to track a user's primary and secondary referrals. My user table looks like:
users table
name, varchar
email, varchar
referral_id, varchar
referrer_id, varchar
I currently access the primary referrals/referrer using the following:
public function referrer()
{
return $this->belongsTo(User::class, 'referrer_id', 'referral_id');
}
public function primaryReferrals()
{
return $this->hasMany(User::class, 'referrer_id', 'referral_id');
}
I'm trying to figure out how I can access the "secondary" referrals...for example.
User A invites User B. User B then invites Users D, E, F. From the User A model I want to be able to call something like $user->secondaryReferrals and get users D, E, F.
I'm guessing I need to use something like:
public function secondaryReferrals()
{
return $this->hasManyThrough(
User::class,
User::class,
'referrer_id',
'referrer_id',
'referral_id',
'referral_id'
);
}
However I'm not clear on what keys/ids I should be supplying...or if this is even the right bit to use. I tried a mix but I keep getting ambiguous column name errors when using sqlite and other errors when using the mysql driver.
UserA: {
referer_id: null,
referral_id: 'abc'
}
UserB: {
referrer_id: 'abc',
referral_id: 'def'
}
UserC: {
referrer_id: 'def',
referral_id: 'ghi'
}
I want to be able to access User C from User A through User B's referral code.
You can't use a HasManyThrough relationship here because there is no way to specify a table alias.
You can use the primaryReferrals relationship twice:
public function getSecondaryReferralsAttribute()
{
$this->load('primaryReferrals.primaryReferrals');
return $this->primaryReferrals->pluck('primaryReferrals')->flatten();
}
// $user->secondaryReferrals
I have following tables:
users - id, username, etc.
conversations - id, private, etc.
conversation_user - id, user_id, conversation_id
There are two records in the conversation_user table for each open/started conversation (could be more if a conversation is multi user).
One for user as recipient/recipients, another for a user as sender. Let's say: user_id=1, conversation_id=1 and user_id=2, conversation_id=1.
How can I select all users/usernames I have an open conversation with. All the participants, to be exact.
I assume I need to get a conversation id's I'm a participant at and then do a reverse lookup for other users in the conversation. But no luck so far... This reverse lookup is where I got stuck.
I'm playing with Laravel 5.3 and MySQL.
First of all, you need a has_started_conversation kind of boolean on your pivot table, conversation_user.
As noted in the docs, you need to define the relationships between your Conversation and User models.
User
class User extends Model
{
public function conversations()
{
return $this->belongsToMany('App\Conversation')->withPivot('has_started_conversation');
}
}
Conversation
class Conversation extends Model
{
public function users()
{
return $this->belongsToMany('App\User')->withPivot('has_started_conversation');
}
}
Then
// get a users conversations
$conversations = \App\User::first()->conversations;
// select a single conversation, or maybe multiple with a for loop?
$important_conversation = $conversations->random();
// get the participants of that conversation
$participants = $important_conversation->users;
I have 5 models configured. Customer, Environment, Object, ServiceRole and Service. I've set up the appropriate eloquent relationships in each of the models.
Customers have many Environments.
//Customer Model
public function environments()
{
return $this->hasMany('App\Environment');
}
Environments belong to one Customer.
Environments belong to many Objects.
//Environment Model
public function customer()
{
return $this->belongsTo('App\Customer');
}
public function objects()
{
return $this->belongsToMany('App\Object');
}
Objects belong to many Environments.
Objects belong to many ServiceRoles.
//Object Model
public function environments()
{
return $this->belongsToMany('App\Environment');
}
public function serviceRoles()
{
return $this->belongsToMany('App\ServiceRole');
}
ServiceRoles belong to many Objects.
ServiceRoles belong to one Service.
//ServiceRole Model
public function objects()
{
return $this->belongsToMany('App\Object');
}
public function service()
{
return $this->belongsTo('App\Service');
}
Services belong to many ServiceRoles.
public function serviceRoles()
{
return $this->hasMany('App\ServiceRole');
}
--SQL--
customers: id, name
objects: id, name
environments: id, name, customer_id
environment_object: id, environment_id, object_id
service_roles: id, name, service_id
object_service_role: id, object_id, service_role_id
services: id, name
1) What would be the simplest method to retrieve all of the Objects that associated to the Customer (across all of the related Environments)?
Looking to do something like: $customer->objects
2) How can I then retrieve all the Services of the Objects associated to the Customer, as each Object has a ServiceRole that maps to a Service.
Looking to do something like: $customer->services
It will be good to post all your relationships. But if you say you have appropriatly set up your relationships then the following should work.
1. Customer::with('environments.objects')->get();
but if its for only a customer do
Custmer::with('environments.objects')->find($id);
2. Customer::with('environments.objects.roles')->get();
for only a customer do
Customer::with('environments.objects.roles')->find($id);
I'm new to laravel relationship so many apologizes if it's just dumb question. I'm using a pivot table named users_email on the project to get Emails of users. Pivot table contains the foreign key Uid and Email_id. Uid references users table
primary key and the same as Email_id. I can get the result while joining them using QueryBuilder.
$recent_inbox_email=DB::table('users_email')->
join('email','users_email.email_id','=','email.Id')->
join('users','users_email.Uid','=','users.Id')->
where('users_email.Uid','=',$Uid)->
where('email.draft','<>','true')->
where('email.trash','<>','true')->
where('email.status','=','unread')->count();
here's how I define the relationship in my models
public function getUid()//User Model
{
return $this->hasMany("User_Email",'Uid');
}
public function getEmId()//Email Model
{
return $this->hasMany("User_Email",'email_id');
}
//User_Email Model
public function email()
{
return $this->belongsTo('Email','Id','email_id');
}
public function user()
{
return $this->belongsTo('User','Id','Uid');
}
Now I want to query something like this using Eloquent
$query= select * from users_email inner join
email on users_email.email_id=email.Id
inner join users on users_email.Uid=users.Id
where users.Id=users_email.Uid limit 0,10
foreach($query as $emails)
{
echo $emails->f_name;
echo $emails->Message
}
DB designer Pic
Link to image
Thanks
There are no dumb questions. I'll try to give you an explanation! I'm not a pro, but maybe I can help.
Laravel uses some conventions that are not mandatory, but if you use them, things work like a charm.
For example, as a general recommendation, tables should be named in plural (your table users is ok. Your "email" table should be "emails"). The model, should be named in singular. This is User.php for table users, Email.php for table emails.
"The pivot table is derived from the alphabetical order of the related model names...", in this case "email_user". I repeat, you are not obliged to name them like this, as you can specify the table for the model setting the $table property in the model.
Once you have set up things like this, you only have to add this to your User model:
public function emails()
{
return $this->belongsToMany('Email');
}
And in your Email model:
public function users()
{
return $this->belongsToMany('User');
}
The "User" and "Email" between parentheses is the name of the related model.
And that's it. You can now do this:
$user = User::find(1);
foreach($user->emails as $email) {
echo $email->subject . '<br>';
echo $email->message . '<br>';
}
If you decide not to follow conventions, you can still use Eloquent relationships. You have to set up the relationship like this:
public function nameOfRelation()
{
return $this->belongsToMany('NameOfRelatedModel', 'name_of_table', 'foreign_key', 'other_key');
}
In the case of the User model for example:
public function emails()
{
return $this->belongsToMany('Email', 'users_email', 'Uid', 'email_id');
}
And in the email model, the other way round.
The answer got long! I didn't test the code, but this should give you an idea!
You can always check the official Laravel documentation, it is really helpful!
http://laravel.com/docs/4.2/eloquent
Hope I helped