`Row `1` must be array` in laravel - laravel

I am trying to import csv file in laravel with help of maatwebsite . I have query which is bringing data from two table both have relation with each other. it is exporting only one table data when I try to fetch data of both tables it gives me an error of Row1must be array
$data = SaleOrder::where('id',$id)->with('customers')->get()->toArray();
return Excel::create('Packlist Sale Order '.$id, function($excel) use ($data) {
$excel->sheet('mySheet', function($sheet) use ($data)
{
foreach($data as $customer)
{
$sheet->fromArray($customer['customers']);
}
$sheet->fromArray($data);
});
})->download('xlsx');
I want fetch data of both tables in csv file

You are using a with('customers') which means $data is a multi dimensional array with customers already in it, and likely breaking $sheet->fromArray($data);
If you remove the with('customers') from your query and do this:
foreach($data as $salesOrder)
{
$sheet->fromArray($salesOrder->customers()->get()->toArray());
}
This will load it on demand and leave it out of $data.

Related

Data filtering query in Laravel many-to-many relationship

there is a table named products and another table named features that have a many-to-many relationship.
I want to write a query that returns products that, for example, have features 2, 3, and 11 at the same time. Now I wrote the following command
$params = [2,3,11];
$products = Product::with('photos')
->whereHas('features', function ($q) use ($params) {
$q->whereIn('feature_id' , $params);
})
->whereIn('category_id', $ids)
->orderByRaw($sortBy)
->paginate($paginate);
when I use whereIn, it works in the form of OR and shows me products that either have the feature 2 or 3 or 11..
I want it to be in the form of AND, which means it will only find products that have all the desired features together
$products = Product::with('photos')
->whereHas('features', function ($q) use ($params) {
foreach($params as $p) {
$q->where('feature_id', $p);
}
})
->whereIn('category_id', $ids)
->orderByRaw($sortBy)
->paginate($paginate);
and this query that I wrote returns empty data.

Export large data using WhereIn and cursor in Laravel

I have a collection of 25k rows that I get from a CSV file, which contains a URL column.
How can I perform an optimized query using the value of the URL column?
This is what i have so far:
public function export()
{
$collection = FastExcel::import($file);
$urls = $this->getData($collection);
FastExcel::data($urls)->export('file.xlsx');
}
// generator function
public function getData( $collection )
{
$query = MyModel::select('url', 'views')
->whereIn('url', $collection->pluck('url'))
->cursor();
foreach ($query as $row) {
yield $row;
}
}
This works using little memory, but the query time is very high.
Memory usage 54 MB
Query: select `url`, `views` from `my_table` where `url` in... 297.36ms
I am using Laravel 9, MySQL 5.7
Build your query with query builder ( db raw ) to get one result , then do your magic

Select specific column on lazy eager loading query Laravel

I am using Laravel 8.
Assume the show() function is called in a Controller, providing me with a specific Location.
The goal is to return a view with that location, but adding relation data to the $location variable beforehand. Since there already is a location but it is missing some data, I call the load function to lazy eager load the relation. Also, I need the soft Deleted customers as well, thus using a closure like so:
public function show(Location $location)
{
$location = $location->load([
'customers' => function($query) {
$query->withTrashed();
}]
);
return view('location.EditLocationView', ['location' => $location]);
}
Now, I face a problem. I only need the customers names stored inside of the $location variable, preferably in an array "['James', 'Christian' ... ]"
How do I do that? The code should probably look like something somilar to this:
public function show(Location $location)
{
$location = $location->load([
'customers' => function($query) {
$query->withTrashed()->select('names')->toArray();
}]
);
return view('location.EditLocationView', ['location' => $location]);
}
And $location should look like this:
$location =
name: ..
lat: ..
lng: ..
customers: ['James', 'Christian' ... ]
Thanks for your help.
The problem with eager load is you can't select only name column you will need to select the foreign key also in order to properly map the data with location like
$query->withTrashed()->select(['location_id','names'])
If its a single $location record then you could also perform lazy load because it will fire one query (same as above eager load case) and then you can store customers name in another variable and pass it to view.
$customers = $location->customers()->withTrashed()->pluck('name')->toArray();

how to set the columns in an excel using Maatwebsite using laravel 5.4

Hi i have this download csv. Now my problem is i want to get the certain columns for my excel file not all fields from the database to be pulled to csv. Now my download csv works good and could download the data. Now i want that only certain columns to be displayed into my csv file. the getCell code wont work. This is my code below
//download csv all pending
public function downloadExcelAllPending($type){
$data = BookingHistory::orderBy('checkin_date', 'desc')->get()->toArray();
return Excel::create('booking_history', function($excel) use ($data) {
$excel->sheet('mySheet', function($sheet) use ($data)
{
$sheet->getCell('A1')->setValue('first_name');
$sheet->fromArray($data);
});
})->download($type);
Now this line of code here $sheet->getCell('A1')->setValue('first_name'); won't work. Can someone help me figured this thing out?. Any help is muchly appreciated. TIA.
You could select only the desired attributes when fetching the data from the database:
public function downloadExcelAllPending($type)
{
$data = BookingHistory::orderBy('checkin_date', 'desc')
->select([
'checkin_date',
// your other attributes
])
->get()
->toArray();
return Excel::create('booking_history', function ($excel) use ($data) {
$excel->sheet('mySheet', function ($sheet) use ($data) {
$sheet->fromArray($data);
});
})->download($type);
}

How to prevent duplication when I reload my page to insert csv file to the database in laravel

Data duplicates in the database when I reload the code using laravel
I have tried to use laravel methods like "updateOrInsert" or "updateOrCreate " to prevent csv data duplication but it does't work? Please help!!
Here is the section how to import csv data to database
public function importCsv()
{
$products = $this::parseCsv('data.csv');
var_dump($products);
if (!empty($products)) {
foreach($products as $product) {
Product::create($product);
}
}
DB::table('products')
->updateOrInsert(
['name' => 'Jonathan', 'job'=>'consult'],
['name' => 'Johana']
);
return $this->parseCsv('data.csv');
}
Csv data duplicates in the database
Laravel determines whether the record already exists in the database by attempting to find it using the id of the record, not by comparing the data.
Your CSV file needs to have an id field that matches in both the CSV record and the database record.

Resources