how to make relation between table and array of ids from another table laravel - laravel

i have 2 tables, stores and products
stores table has field called products_ids
in this case i am saving the products in the stores by their ids in products_ids field as an array like this [1,2,3,4,5] i know it's not good practice to do it like this but this is the situation.
how can i make a relation in the model to achieve thing like this
Store::with('products')->get();
thanks

I don't know if this would work for you, but try it anyway:
in your Store model add the following:
public function products ()
{
return Product::whereIn('id', $this->products_ids)->get();
}

Related

How to get the record that was inserted by sync

Is there a way to get the record or records that was inserted by sync method?
Something like:
$shop_product = $shop->products()->sync(1);
so I want now $shop_product to be instance that contains the records
{
shop_id: 1,
product_id: 1
}
The sync method updates your products relationship with shop.
So calling $shop->products should return you only products that you synced.
There is no reason to access pivot table data unless you have some additional data there. If you have then you should define in your model relationship that you want it. Like:
return $this->manyToMany(.....)->withPivot(['data_field_name'])
If you are working with shop products you probably don't need pivot table. Usually one product can be related to only one shop so relation will be $this->hasMany(Product::class) and your products table will have shop_id

Laravel hasOne + group_by, get sum

I'm currently scratching my head with this one.
What I have.
$entries = Meta::whereIn('settlement_id', [1])->groupBy('client_id')->get();
Meta::model() has a hasOne relation with other tables, in my example with a Sport table. With one attribute in my array I can achieve what I want.
So in a loop I have my field available $entry->Sport->amount this works perfectly.
What I need.
$entries = Meta::whereIn('settlement_id', [1,2,3])->groupBy('client_id')->get();
Now when I expand my array with multiple id's, I expect that $entry->Sport->amount returns the sum of all id's. But it doesn't.
I can't figure out what i'm doing wrong.
All help is appreciated.
Your hasOne relation means that each Meta will have a separate Sport, so when you loop $entries each $entry->Sport will have the amount related to the current Meta, not a sum of all of them.
If you want to have the sum of Sport amount for specific Metas it might be easier to make a query from the Sport model, something like this (I don't know how your relations is setup so this is just an example):
Sport::whereIn('meta_id', [1,2,3])->sum('amount');
Thats correct, is there a way that I can achieve this? By changing hasOne to something else?
I don't want to query each specific related Meta table.
public function Sport()
{
return $this->hasOne('App\Sport', 'settlement_meta_id');
}
my database table Sport looks like this:
protected $fillable = [
'settlement_meta_id',
'bet',
'payout'
];

Laravel how many relationship can be chained

I have a database composed by users, users_child, child.
I create a ONE to MANY relationship between Users and users_child, then i create a relationship between users_child and child. Now the below code work:
$test = users::find(1)->users_child
$test1= users_child::find(1)->child
Now i want to know if is possible to create a single row that link the three table like this:
$test = users::find(1)->users_child->child
I create the relationship in the model but in the db i don't create Foreign Key, it's a problem? on the model i specify the field for link table.
http://laravel.com/docs/5.1/eloquent-relationships#querying-relations
You can chain relationships like this:
$user = Users::with("users_child.child")->where("id",1)->first();
Each point will mean a relation stored in the first.
Out of users users_child will be taken and out of users_child child will be taken. (Relations)
foreach($user->users_child as $user_child) {
$user_child->child;
}
will get you the data you need.

Updating a pivot table in Eloquent

I've got a many to many relationship between a student and an institution_contact.
students should only ever have two institution_contacts and I have an attribute on the pivot table named type to be set as 1 or 2.
So, my pivot table looks like this:
institution_contact_student: id, institution_contact_id, student_id, type
I've run into difficulty in deciding how to approach the issue of adding/updating the pivot table. Let's say I have 100 students and I want to assign them a contact with the type of 1.
My current solution is to delete the contact then add it:
$students = Student::all(); // the 100 students
$contactId = InstitutionContact::first()->id; // the contact
foreach ($students as $student) {
// remove existing contact
$student
->institutionContacts()
->newPivotStatement()
->where('type', 1)
->delete();
// add new contact
$student
->institutionContacts()
->attach([$contactId => ['type' => 1]]);
}
However, I'm thinking that this is going to hit the database twice for each student, right? So would I be better off creating a model for the pivot table and removing all entries that matched the student id and the type then simply adding the new ones? Or would creating a model for the pivot table be considered bad practice and is there a better way of accomplishing this that I've missed?
Please note the reason I'm not using sync is because I'm relying on the type attribute to maintain only two contacts per student. I'm not aware of a way to modify an existing pivot without causing issues to my two contacts per student requirement.
Edit:
Instead of creating a model I could run the following code to perform the delete using DB.
DB::table('institution_contact_student') // the pivot table
->whereIn('student_id', $studentIds)
->where('type', 1)
->delete();
If I have understood your question correctly then you can use the updateExistingPivot method for updating your pivot table.But first of course you have to define the pivot in your relationship. For instance,
public function institutionContacts(){
return $this->belongsToMany('institutionContact')->withPivot('type');
}
after this, all you have to do is use the following code:
$student
->institutionContacts()
->updateExistingPivot($contactId, ["type" => 1]);
Hope this helps.

return separate result for each relation in many to many

Hi i have a many to many relationship with the following structure:
services
apps
service_app
I would like to have an eloquent query to return a separate result for each relationship(basically the pivot table). I have the following :
$all = App::with('services')->get();
this will return an app with nested services, I would like to have this return a separate result for each app-service combination along with data from the pivot table. how is this possible using eloquent?
It's a bit strange, but it can easily be done if you don't think of the pivot table as a pivot table, but as an AppService.
So what you can do is create a model for it, probably named AppService. In that model, you would then have 2 belongsTo() relationships. One for App and one for Service.
Then you can query your pivot table directly and use those relationships to get what you need.
$appServices = AppService::all();
foreach($appServices as $appService) {
echo $appService->app->description;
echo $appService->service->description;
}

Resources