eloquent model laravel get one to many inside loop - laravel

i have laravel project ..
and i have to get users
this is my
<table class='table table-responsive table-hover table-responsive draggable' border='5'>
<thead>
<tr class='warning'>
<input id='searchAjaxText' type='text' class='form-control' placeholder='رقم الهاتف أو اسم المستخدم أو الايميل'/>
</tr>
</thead>
<tbody id='searchAjaxResult'>
</tbody>
</table>
and this is my js as key up
$("#searchAjaxText").keyup(function(){
var searchAjaxText = $(this).val();
if(searchAjaxText != '')
{
$.get
(
"/users/search/"+searchAjaxText+"",
{
searchAjaxText:searchAjaxText
},
function(data)
{
$("#searchAjaxResult").html(data)
console.log(data);
}
)
}
})
and this is my Route code
Route::get("/users/search/{keyword}",'UsersController#searchScoop');
and this is my controller code
public function searchScoop($keyword)
{
$user = User::searchScoop($keyword);
return $user;
}
and this is my searchoop function inside the model
public static function searchScoop($keyword)
{
$users = User::where('username','like','%'.$keyword.'%')->
orwhere('email','like','%'.$keyword.'%')->
orwhere('phone','like','%'.$keyword.'%')
->get(['id','username','phone','division','permission']);
return $users;
}
now i get this on my console
Array[1]
0
:
Object
division : 3
id : 15
permission : 3
phone :"0788511619"
username : "bashar"
now the permission and the division is numbers ..
how can i get the permission name from the Permission model and the division name fro mthe Division model by the id i gat it from users table ..

Load permissions for each user by using with() method:
$users = User::where('username', 'like', '%'.$keyword.'%')
->orwhere('email', 'like', '%'.$keyword.'%')
->orwhere('phone', 'like', '%'.$keyword.'%')
->with('permissions', 'divisions')
->get(['id', 'username', 'phone', 'division', 'permission']);
One to many relationship should be defined like this:
public function permissions()
{
return $this->hasMany('App\Permission', 'permission', 'id');
}

Related

Differentiate two views with buttons

I have a view in which I display two data that I take from a table of a DB and next to these data I have two buttons that take me to the same view in which I need to display other things.
What I can't figure out is, how do I differentiate the view AFTER pressing the button?
Here there are the images of the two view:
https://imgur.com/a/i5BcPaw
The code is the following:
Controller:
<?php
namespace App\Http\Controllers;
use App\Models\Device;
use App\Models\DataFromRasp;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
class DeviceController extends Controller
{
public function index()
{
$data=Device::all();
return view('backend.auth.user.device', compact("data"));
}
public function create()
{
}
public function store(Request $request)
{
}
public function show(Device $deviceID)
{
}
public function edit(Device $device)
{
//
}
public function update(Request $request, Device $device)
{
//
}
public function destroy(Device $device)
{
//
}
/**
* Displays all data present in the table data_from_rasps
*
* The data are all the devices that the raspberry can capture
*/
public function visualizeData()
{
$data=DataFromRasp::paginate(10);
return view('backend.auth.user.dictionary', compact("data"));
}
/**
* Raspberry capture and send the data to the DB and save in another
* table of the same DB the MAC addresses of interest
*/
public function getData(Request $request)
{
$m_data = $request->get('m_data');
$r_data = $request->get('r_data');
DataFromRasp::create(['MAC' => $m_data, 'RSSI' => $r_data]);
if(($m_data == 'C4:A5:DF:24:05:7E') and Device::where('MAC_ADDR', $request->m_data)->doesntExist()){
Device::create(['USERNAME'=>'Device1','MAC_ADDR' => $m_data]);
}
if(($m_data == '70:1C:E7:E4:71:DA') and Device::where('MAC_ADDR', $request->m_data)->doesntExist()){
Device::create(['USERNAME' => 'Device2','MAC_ADDR' => $m_data]);
}
}
public function scan()
{
$process = new Process(['C:\Simone\Università\Tirocinio\laravel-boilerplate-master', 'prova.py']);
$process->run();
if (!$process->isSuccessful()) { throw new ProcessFailedException($process); }
return redirect()->route('dict');
}
public function singleDev(Device $deviceID){
$data = DataFromRasp::select('RSSI', 'created_at')->where('MAC', 'C4:A5:DF:24:05:7E')->get();
$time_array = [];
$rssi_array = [];
$cnt = 0;
foreach($data as $dataItem){
array_push($time_array, $dataItem->created_at->format('H:i:s'));
array_push($rssi_array, $dataItem->RSSI);
}
return view('backend.auth.user.singleDevice', compact("time_array", "rssi_array"));
}
}
View where I select the device:
#extends('backend.layouts.app')
#section('content')
<table class="table">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">USERNAME</th>
<th scope="col">MAC ADDRESS</th>
</tr>
</thead>
<tbody>
#foreach ($data as $item)
<tr>
<th scope="row">{{$item->id}}</th>
<td>{{$item->USERNAME}}</td>
<td>{{$item->MAC_ADDR}}</td>
<td>
Select
</td>
</tr>
#endforeach
</tbody>
</table>
#endsection
Does anyone know how to do this?
Thanks in advance
Try to use this code
Select
Instead of
Select
Updated!
I a little bit didn't get what you trying to achieve, but why didnt your try to add another button next to it, to show another view?
You could create an if statement to determine if one of the buttons is pressed whenever you load the page.
In blade
<button type="submit" name="device_id" value="$item->id">Select</button>
In controller
$data=Device::all();
$singleDevice = Device::where('id', '=', Input::get('device_id'))->first();
if($singleDevice === null)
{
return view('backend.auth.user.device', compact("data"));
}
else
{
$time_array = [];
$rssi_array = [];
$cnt = 0;
foreach($singleDevice as $dataItem){
array_push($time_array, $dataItem->created_at->format('H:i:s'));
array_push($rssi_array, $dataItem->RSSI);
}
return view('backend.auth.user.singleDevice', compact("time_array", "rssi_array"));
}

Laravel 7 Search Model

I am trying to build a search engine but I am coming up blank with how to build the search. I have about 5 input fields for the user to search (heading , usersGroup , course ,title(question type). I am test one code ,and its work just for search according the title,but for other search it dose not work ,what should I do??
public function show_page_search()
{
$headings = heading::all();
$usersGroup = usersGroup::all();
$courses = course::all();
$questionType = $this->questionType;
return view('Admin.Page.Question.search', compact(['headings', 'usersGroup', 'courses', 'questionType']));
}
public function get_data_search(Request $request)
{
$questions = question::Where('title', 'LIKE', "%{$request->title}%")->get();
if ($request->type !== null)
$questions = $questions->where('type', $request->type)->all();
Its my Model :
class question extends Model{
protected $table = 'questions';
protected $guarded = ['id'];
public function headings()
{
return $this->belongsToMany(heading::class, 'question_headings', 'question_id', 'heading_id');
}
public function userGroup()
{
return $this->belongsToMany(usersGroup::class, 'question_users_groups', 'question_id', 'users_groups_id');
}
public function opt()
{
return $this->hasMany(questionOpt::class, 'question_id');
}
public function answer()
{
return $this->hasMany(answerQuestion::class, 'question_id');
}
it is my view :
<tbody class="text-center">
#forelse(session()->get('questions') as $question)
<tr>
<th scope="row"><span
class="badge badge-success p-2">{{ $loop->iteration }}</span></th>
<td>
#foreach($question->headings as $heading)
<span>{{$heading->title}}, </span>
#endforeach
</td>
<td>
#foreach($question->userGroup as $userGroup)
<span>{{$userGroup->name}}, </span>
#endforeach
</td>
<td>{{get_question_type_name($question->type)}}</td>
<td>{{$question->title}}</td>
<td>
get and all returns the result as a collection. So before calling any method that would return the result, you would build the complete query.
So change this:
public function get_data_search(Request $request)
{
$questions = question::Where('title', 'LIKE', "%{$request->title}%")->get(); //remove this get()
if ($request->type !== null)
$questions = $questions->where('type', $request->type)->all(); //remove this all()
To this:
public function get_data_search(Request $request)
{
$questions = Question::where('title', 'LIKE', "%{$request->title}%");
if ($request->type !== null)
$questions->where('type', $request->type); //use `like` if you want
if (another condition)
$questions->where('column', 'value');
//and finally call get() or all() or paginate() to get the final result
$questions->get();
return view('view', compact('questions'));
}

Invalid argument supplied for foreach() on laravel

I have like error message : Invalid argument supplied for foreach()
For my method index() I have this:
public function index(Request $request)
{
if(\Auth::user()->hasRole('admin')){
if($request->has('search'))
$remarks = Remark::orderBy('instruction', 'asc')->where('instruction','like','%'.$request->input('search').'%');
else
$remarks = Remark::all();
}else{
\Auth::user()->load('remarks');
$remarks = \Auth::user()->remarks;
}
return view('admin.remarks.index', compact('remarks'));
}
Concerning my index.blade.php I have my loop "for" which is like this:
<th>Instruction</th>
<th>Description</th>
<th>Date seance</th>
<th>Name Candidate</th>
<th>Email</th>
</tr>
</thead>
#foreach($remarks as $remark)
<tr>
<td> {{$remark->instruction}}</td>
<td> {{$remark->description}}</td>
<td> {{$remark->seances->date_seance}}</td>
<td> {{$remark->seances()->first()->candidates->name}}</td>
<td> {{$remark->seances()->first()->candidates->email}}</td>
<td>
Do you have an idea of my problem please? I don't understand ??
You need to call get() after the Eloquent Query Builder to fetch the data from the database. Unless it's an Eloquent Query Builder Object (which is not iterable, so cannot be used in a for loop).
The function get() will return the result as a Laravel Collection (which is iterable).
$remarks = Remark::orderBy('instruction', 'asc')
->where('instruction','like','%'.$request->input('search').'%')
->get();
you should querying from database not from session and don't forgot define relations on users model :
on users model:
public function remarks(){
return $this->hasMany(Remark:class)
}
on your controller
public function index(Request $request)
{
if(\Auth::user()->hasRole('admin')){
if($request->has('search'))
$remarks = Remark::orderBy('instruction', 'asc')->where('instruction','like','%'.$request->input('search').'%');
else
$remarks = Remark::all();
}else{
$user = Users::find(Auth::id());
$remarks=$user->remarks
}
return view('admin.remarks.index', compact('remarks'));
}

unserialize object export Excel blade view

I try to export a excel file from a blade view with an unserialize object from a text column in my database but i get an error .
Error:
Call to undefined method Illuminate\Database\Query\Builder::transform()
Here is my controller :
public function ExportExcel($id)
{
$order = Order::find($id);
$order->transform(function ($order , $key){
$order->cart = unserialize($order->cart);
return $order;
});
Excel::create('facture', function($excel) use ($order) {
$excel->sheet('Excel', function($sheet) use ($order) {
$sheet->loadView('cotisation_structure.factureExcelsingle')->with(['order' => $order]);
});
})->export('xls');
}
Here is my blade view :
<html> <body>
<thead>
<tr>
<th>N° Facture</th>
<th>N° licence</th>
<th>Nom</th>
<th>Prénom</th>
<th>Type d'activité</th>
<th>Saison</th>
<th>Mode de paiement</th>
<th>Montant</th>
<th>Date Achat</th>
</tr>
</thead>
<tr>
<td>{{$order->num_facture}}</td>
<td>{{$order['item']->num_licence}}</td>
<td>{{$order['item']->lb_nom}}</td>
<td>{{$order['item']->lb_prenom}}</td>
<td>{{$order['item']->activite_licencie->lb_activite}}</td>
<td>{{$order['item']->saison->lb_saison}}</td>
<td>{{$order->payment_method}}</td>
<td>{{$order['price']}}</td>
<td>{{$order->date_achat}}</td>
</tr>
It seems that Transform methode doesn't work for an object , only for a collection.
Eloquent find method return a single model instance Instead of returning a collection of models.
So transform method only working on collection not on single model instance.
Try this one
public function ExportExcel($id)
{
$order = Order::find($id);
$order->cart = unserialize($order->cart);
Excel::create('facture', function($excel) use ($order) {
$excel->sheet('Excel', function($sheet) use ($order) {
$sheet->loadView('cotisation_structure.factureExcelsingle')->with(['order' => $order]);
});
})->export('xls');
}
Note: Transform function working on collection not on a single object.

get only newest object from a model - laravel eloquent

I have two models: Supplier and Quotation. I can use a foreach to list all quotations of a supplier:
// in my `Supplier` model:
public function quotations()
{
return $this->hasMany('App\Models\Quotation', 'supplier_id');
}
And now I want to print only the most recent quotation. The best I can figure out is this function in model:
public function newestQuotation()
{
return $this->hasMany('App\Models\Quotation', 'supplier_id')->orderBy('offered_at','desc')->limit(1);
}
and this foreach loop:
#foreach($o->newestQuotation as $q)
#include('displaymodules.module_quotations_mini', array('bg_color' => 'bg-danger'))
#endforeach
TO DO:
The above code does the job... but how it can be done properly? I am thinking of doing a helper, but doing the function in my models seems more like a good practice.
Thank you
Edited:
maybe I wasn't clear enough... I don't want to use foreach to access the object.
What I want is a snippet like this:
#include('displaymodules.module_quotations_mini', array( 'q' => $o->latestQuotations))
I get such an object when the query has the ->first(), but not when it has '->get()`.
when I do
$latestQuotation = App\Models\Quotation:where('supplier_id', 3)->orderBy('offered_at, 'desc')->first();
to get what I want without foreach I use this this temporary solution
<?php
$latestQuotation = App\Models\Quotation::where('supplier_id', $o->id)->orderBy('offered_at', 'desc')->first();
?>
#if(isset($latestQuotation))
#include('displaymodules.module_quotations_mini', array('bg_color' => 'csch_subtle_3', 'q' => $latestQuotation))
#endif
Attempts to implement Krishan Koenig's answer
attempt #1
<?php $latestQuotations = $o->latestQuotations(); ?>
{{print_r($latestQuotations)}}
Result: domain.dev is currently unable to handle this request.
HTTP ERROR 500
attempt #2
{{$o->latestQuotations()->offered_at}}
or
{{$o->latestQuotations->offered_at}}
Result:
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$offered_at (View:\resources\views\leads\_show_bestoffers.blade.php) (View: \resources\views\leads\_show_bestoffers.blade.php)
attempt #3 - my desired solution
#include('displaymodules.module_quotations_mini', array('bg_color' => 'csch_subtle_5', 'q' => $o->latestQuotations))
Result:
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$offered_at (View:\resources\views\leads\_show_bestoffers.blade.php) (View: \resources\views\leads\_show_bestoffers.blade.php)
You could create a new scope in related model, call it like latest:
public function scopeLatest($query)
{
return $query->orderBy('offered_at','desc')->limit(1);
}
and then in your relationship:
public function newestQuotation()
{
return $this->hasMany('App\Models\Quotation', 'supplier_id')->latest();
}
For example:
Quotation.php model
class Quotation extends Model
{
protected $primaryKey = 'id';
function withSupplier() {
return $this->hasMany('App\Models\Quotation', 'id', 'supplier_id')->orderBy('offered_at','desc');
}
public function newestQuotation($supplier_id){
News::with('withSupplier')->where('supplier_id', $supplier_id)->get();
}
}
in contriller:
public function pageQuotations(Quotation $quotation)
{
$quotations = $quotation->newestQuotation(1); //id Supplier
return view('displaymodules.quotations', $quotations);
}
in quotations.blade.php (example)
<table>
<tbody>
#foreach ($quotations as $quotation)
<tr>
<th>{{ $quotation->title }}</th>
<td>{{ $quotation->withSupplier()->title }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
You can create a new relatiotion in Supplier Model as:
public function newestQuotation()
{
return $this->hasOne('App\Models\Quotation', 'supplier_id')->orderBy('offered_at', 'desc');
}
Then you can query it as:
$supplieres = Supplier::with('newestQuotation')->take(20)->get();
#foreach ($supplieres as $supplier)
{{ $supplier->newestQuotation->title }} // just an example
#endforeach
Update
Try your query as:
$supplier = Supplier::where('id', $id)->first();
$latestQuotation = $supplier->newestQuotation;
Create a scope and use your existing relationship!
public function quotations()
{
return $this->hasMany('App\Models\Quotation', 'supplier_id');
}
public function scopeLatest($query)
{
return $query->orderBy('offered_at','desc')->limit(1);
}
public function latestQuotations()
{
return $this->quotations()->latest();
}
And in your Controller you query them with
//...
$latestQuotations = $supplier->latestQuotations();
Edited Version:
// supplier model
public function quotations()
{
return $this->hasMany(Quotation::class);
}
public function scopeLatest($query)
{
return $query->orderBy('offered_at','desc');
}
public function latestQuotations()
{
return $this->quotations()->latest()->get();
}
// web route
Route::get('/', function () {
$latestQuotations = App\Supplier::first()->latestQuotations();
return view('welcome', compact('latestQuotations'));
});
// welcome view
{{ $latestQuotations }}
...worked for me.
The most simple solution is
$entity = $collection->first();
Then, whateverthe count of the collection, the result is a single object.
This allows to use terms such as $entity->id or $entity->name.

Resources