Attach Array Data to Laravel Model - laravel

I have a product table which has column name unit_id, I have approximate 15 units data. And I stored a custom key of unit to the product as you can check in the screenshot.
And the Units data is stored in settings table, in a single row and meta_value holds all the units data in json format
Now the problem is I have to run two queries every time for products, need help to know more convenient.
// For Products
Product::where('id', 1)->first();
// For settings
Settings::where('meta_key', 'product_units')->first();
Is there any way so that I attach the Settings data in Product model, the problem we get for multiple products not single.

You can try to use a mutator inside the Products model https://laravel.com/docs/5.1/eloquent-mutators.
public function getProductUnitsAttribute() {
return Settings::where('meta_key', 'product_units')->first();
}
so you can do this to get the settings
$product = Product::where('id', 1)->first();
$product->product_units;
but i don't think that this is a good practice.

Related

How to use an array as a foreign key in a model and build a hasMany relationship in laravel

This is my schema as follows:
Medicines
id
price
description
etc..
Ecommerce Orders(has many Medicines)
id
user_id
products (array that holds the id's of the medicine's and quantity)
And in my EcommerceOrders Model i have
protected $casts = [
'products' => 'array',
];
public function items()
{
return $this->hasMany(Medicines::class,'id','products')->withTrashed();
}
What I'm trying to do is to create a relationship between ecommerceOrders and medicines so when i get the data of an order that a client has made i also get the data of the products he has orederd
How can i do this with the foreign key in this instance being an array
You need another table called a pivot table, "ecommerce_order_medicines" with the fields medicine_id, ecommerce_order_id, qty
You would have a record for each different medicine that belongs to the ecommerce order.
You should not store it the way you are doing right now, you won't be able to make any relationship with it stored as an array like that. You also are making it much more difficult to do any kind of reports in the future, because you won't be able to properly query your database when it's stored as an array with ID's and QTY in the same column with no relationship. You will likely have to process large sets of data through PHP instead which won't scale very well.

Using Laravel Eloquent to count how many times something exists in an efficient manner

I have a table called rentals, within each row are columns state,city,zipcode which all house ids to another table with that info. There are about 3400 rentals. I am pulling each column to display the states,city and zipcode distinctly. I need to show how many rentals are in each one. I am doing this now via ajax, the person starts typing in what they want to see and it auto completes it with the count, but its slow because of the way im doing it.
$rentals_count = Rentals::where('published',1)->get();
foreach($states as $state) {
echo $state.”-“.$rentals_count->where(‘state’,$state->id)->count();
}
Above is roughly what im doing with pieces removed because they are not related to this question. Is there a better way to do this? It lags a bit so the auto complete seems broken to a new user.
Have you considered Eager loading your eloquent query? Eager loading is used to reduce query operations. When querying, you may specify which relationships should be eager loaded using the with method:
$rental_counts = Rentals::where('published',1)->with('your_relation')->get();
You can read more about that in Laravel Documentation
$rentals = Rentals::wherePublished(true)->withCount('state')->get();
When you loop through $rentals, the result will be in $rental->state_count
Setup a relation 'state' on rentals then call it like this
$rentals_count = Rentals::where('published',1)->with('state')->get()->groupBy('state');
$rentals_count->map(function($v, $k){
echo $v[0]->state->name .' - '. $v->count();
});
Meanwhile in Rentals Model
public function state(){
return $this->hasOne(State::class, 'state'); //state being your foreign key on rentals table. The primary key has to be id on your states table
}

how to make relation between table and array of ids from another table 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();
}

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.

Laravel attach with extra field

I have 3 tables, products, images and product_image. The 3rd one is a pivoting table. Other than product_id and image_id in product_image table, I also have 2 extra fields in this pivoting table: position and type, now for an existing product model A, how do I attach an image to A and at the same time set up its position and type value in that pivoting record? Thanks.
You may try something like this:
$product = Product::find(1);
// if you need also to save the image
$image = new Image(array('foo' => 'bar'));
$product->images()->save($image,array('position'=>'foo', 'type'=>'bar' ));
// if you know image id
$product->images()->attach([$imageId => ['position'=>'foo', 'type'=>'bar']]);
You need just add a array to attach method as second parameter
//for example:
$product->images()->attach($newImage, ['foo'=>'bar']);
It is more eloquent solution.

Resources