Laravel Database Query Builder error with table name - laravel

I'm making a "simple" api for laravel. This api has to handle with filters, pagination and sorting the result. To make this I use laravel query builder. The problem is that it's making a select without a table name, for example:
select * order by `id` asc
My code:
public function index()
{
$request = request();
$query = DB::table('customers')->newQuery();
// Orden
if (request()->has('sort')) {
// Multiorden
$sorts = explode(',', request()->sort);
foreach ($sorts as $sort) {
list($sortCol, $sortDir) = explode('|', $sort);
$query = $query->orderBy($sortCol, $sortDir);
}
} else {
$query = $query->orderBy('id', 'asc');
}
//Filtros
if ($request->exists('filter')) {
$query->where(function($q) use($request) {
$value = "%{$request->filter}%";
$q->where('name', 'like', $value)
->orWhere('address', 'like', $value);
});
}
$perPage = request()->has('per_page') ? (int) request()->per_page : null;
$pagination = $query->get()->paginate($perPage);
$pagination->appends([
'sort' => request()->sort,
'filter' => request()->filter,
'per_page' => request()->per_page
]);
return response()->json(
$pagination
);
}
Error:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error:
1096 No tables used (SQL: select * order by id asc) in file
C:\xampp\htdocs\iService\vendor\laravel\framework\src\Illuminate\Database\Connection.php
on line 664
UPDATE:
return DB::table('customers')->get();
If i use this, the api works fine, I have more apis working. The problem is that I need Query Builder to handle filters, sort, etc...

The problem was the way I instance a new query.
$query = DB::table('customers')->newQuery();
Correct:
$query = Model::query();
For my example:
$query = Customer::query();

Related

Laravel query groubBy condition

I have a dB query where I would like to groupBy() only when conditions are met without using union because of pagination.
Unfortunately groupBy() seems to only work when called on the entire query outside of the loop.
This was made for dynamic filtering from $filterArr. Depending on the array I need to select from different columns of the table.
When the $key=='pattern' I would need the distinct results from its column.
the query looks something like this
select `col_1`, `col_2`, `col_3`
from `mytable`
where (`color` LIKE ? or `pattern` LIKE ? or `style` LIKE ?)
group by `col_2` //<< i need this only for 'pattern' above and not the entire query
Heres the model:
// $filterArr example
// Array ( [color] => grey [pattern] => stripe )
$query = DB::table('mytable');
$query = $query->select(array('col_1', 'col_2', 'col_3'), DB::raw('count(*) as total'));
$query = $query->where(function($query) use ($filterArr){
$ii = 0;
foreach ($filterArr as $key => $value) {
if ($key=='color'){
$column = 'color';
}else if ($key=='style'){
$column = 'style';
}else if ($key=='pattern'){
$column = 'pattern';
$query = $query->groupBy('col_2'); // << !! does not work
}
if($ii==0){
$query = $query->where($column, 'LIKE', '%'.$value.'%');
}
else{
$query = $query->orWhere($column, 'LIKE', '%'.$value.'%');
}
$ii++;
}
});
$query = $query->orderBy('col_2', 'asc')->simplePaginate(30);
I think you can simplify your code a bit:
$query = DB::table('mytable');
$query = $query->select(array('col_1', 'col_2', 'col_3'), DB::raw('count(*) as total'));
$query = $query->where(
collect($filterArr)
->only(['color','style','pattern'])
->map(function ($value, $key) {
return [ $key, 'like', '%'.$value.'%', 'OR' ];
})->all()
)->when(array_key_exists('pattern', $filterArr), function ($query) {
return $query->groupBy('col_2');
});
$query = $query->orderBy('col_2', 'asc')->simplePaginate(30);

Laravel relathionship with query builder get error

I have 3 tables this table is related to, I will call this table with
belanja (parent)
anak_belanja (child)
supplier (has relation with parent)
I can create this relation from parent and child but on table supplier I get an error. Usually I use "with" and I get no error, but now I use query builder and I have a problem
My Belanja Model
public function supplier()
{
return $this->belongsTo(\App\Models\Suplier::class ,'supplier_id');
}
My Anak_Belanja model
public function belanja()
{
return $this->belongsTo(\App\Models\Belanja::class ,'belanja_id');
}
and this is my controller
public function render()
{
$user_id = Auth::user()->id;
$sub = SubRincianUraianKegiatan::where('user_id', $user_id)
->where('id' , $this->newid)
->pluck('uraian', 'id');
$sup = Supplier::all()->pluck('nama' ,'id');
$data = DB::table('belanja AS t')
->select([
't.id',
't.uraian',
't.tgl_belanja',
't.supplier_id',
DB::raw('coalesce(sum(p.harga * p.qty),0) AS total_order')
])
->leftjoin('suplier AS s','t.suplier_id','=','s.id') // on here i think this error
->leftjoin('anak_belanja AS p','p.belanja_id','=','t.id')
->where('sub_id', $this->newid)
->where('uraian', 'like', '%'.$this->search.'%')
->groupBy('t.id')
->groupBy('t.uraian')
->groupBy('t.tgl_belanja')
->groupBy('t.suplier_id')
->paginate(10);
return view('livewire.detail-belanja-lw',
['data' => $data ,
'sup' => $sup,
'sub' => $sub,
]);
}
In my blade I try to add supplier like that
{{$i->supplier->nama}}
but I get an error
Undefined property: stdClass::$supplier
Can someone explain my mistake?
$data = DB::table('belanja AS t')
->select([
't.id',
't.uraian',
't.tgl_belanja',
't.suplier_id',
DB::raw('coalesce(sum(p.harga * p.qty),0) AS total_order'),
DB::raw('s.nama as nama')
])
->leftjoin('suplier AS s','t.suplier_id','=','s.id') // on here i think this error
->leftjoin('anak_belanja AS p','p.belanja_id','=','t.id')
->where('sub_id', $this->newid)
->where('uraian', 'like', '%'.$this->search.'%')
->groupBy('t.id')
->groupBy('t.uraian')
->groupBy('t.tgl_belanja')
->groupBy('t.suplier_id')
->paginate(10);
try this.

Auto inserting table name for subquery/join queries in Laravel (Eloquent)

Here is my query:
PHP
public function find(array $filter = []) : Collection
{
return $this->entity::where($filter)->join('cases_has_services', function ($join) {
$join->on('cases_has_services.cases_id', 'checklists.cases_id');
$join->on('cases_has_services.services_id', 'checklists.item_id');
})->select('checklists.*', 'cases_has_services.quantity')->get();
}
i am receiving the next error:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where
clause is ambiguous (SQL: select `checklists`.*,
`cases_has_services`.`quantity` from `checklists` inner join
`cases_has_services` on `cases_has_services`.`cases_id` =
`checklists`.`cases_id` and `cases_has_services`.`services_id` =
`checklists`.`item_id` where (`id` = 352))
So i fixed my code a little bit:
public function find(array $filter = []) : Collection
{
// TODO fix this
foreach ($filter as $field => $value) {
unset($filter[$field]);
$field = 'checklists.' . $field;
$filter[$field] = $value;
}
return $this->entity::where($filter)->join('cases_has_services', function ($join) {
$join->on('cases_has_services.cases_id', 'checklists.cases_id');
$join->on('cases_has_services.services_id', 'checklists.item_id');
})->select('checklists.*', 'cases_has_services.quantity')->get();
}
But that is not a good practice i think. So, are there any native laravel path to auto insert table name in query with joins?
I mean, how to avoid using that part of code because its a little hacky:
foreach ($filter as $field => $value) {
unset($filter[$field]);
$field = 'checklists.' . $field;
$filter[$field] = $value;
}
Change you $filter variable to:
$filter = ['checklists.id' => 123]

order by clause in codeigniter

I want to fetch the database data by descending order of posted date.Database containing a field named as posted_date. This is my code(in model) for fetch the data.
public function get_data_by_volunteer_id($fields = "*", $volunteer_id)
{
$this->db->select($fields);
$query = $this->db->get_where(self::$tbl_name, array(
"user_id" => $volunteer_id));
return( $query->result() );
}
You can try this
function get_data_by_volunteer_id($fields, $volunteer_id)
{
$query = $this->db->query("SELECT * FROM table_name WHERE user_id = '$volunteer_id' ORDER BY posted_date DESC");
$result = $query->result_array();
return $result;
}
Add following in your query
$this->order_by('posted_date', 'desc');
So your final query would be
$this->db->select($fields);
$this->db->get_where(self::$tbl_name, array(
"user_id" => $volunteer_id));
$this->order_by('posted_date', 'desc');
$query=$this->db->get();
return $query->result();

Translate from CodeIgniter Active Record model to Laravel Eloquent

I am a CodeIgniter trying to adopt Laravel, however, I have been having a lot of problems understanding how to use Eloquent.
I suspect that if I could figure out how to translate some of my CodeIgniter Model methods to Laravel Eloquent I might be able to get on better. Hopefully, this will help others with the same problem.
Could anybody please rewrite the following from CodeIgniter to Eloquent:
public function get_products($product_id = NULL, $category_id = NULL, $limit = NULL)
{
$this->db->select('*, product.id AS product_id');
$this->db->from('product');
$this->db->join('product_unit', 'product.source_unit_id = product_unit.id', 'left');
$this->db->join('stock_levels', 'product.stock_level_id = stock_levels.id', 'left');
$this->db->join('categories', 'product.category_id = categories.cat_id', 'left');
if(isset($product_id)) {
$this->db->where('product.id', $product_id);
}
if(isset($category_id)) {
$this->db->where('product.category_id', $category_id);
}
if(isset($limit)) {
$this->db->limit($limit);
}
#$this->db->order_by('categories.cat_name', 'ASC');
$this->db->order_by('categories.cat_name', 'ASC');
$this->db->order_by('product.name', 'ASC');
$query = $this->db->get();
return $query->result_array();
}
Here's an approximate version of your query, there should be some things to tweak, but I hope you get the idea:
public function get_products($product_id = NULL, $category_id = NULL, $limit = NULL)
{
$query = Product::leftJoin('product_unit', 'source_unit_id', '=', 'product_unit.id')
->leftJoin('stock_levels', 'stock_level_id', '=', 'stock_levels.id')
->leftJoin('categories', 'category_id', '=', 'categories.cat_id');
if(isset($product_id)) {
$query->where('product.id', $product_id);
}
if(isset($category_id)) {
$query->where('product.category_id', $category_id);
}
if(isset($limit)) {
$query->limit($limit);
}
#$this->db->order_by('categories.cat_name', 'ASC');
$query->orderBy('categories.cat_name', 'ASC');
$query->orderBy('product.name', 'ASC');
dd( $query->toSql() ); /// this line will show you the sql generated and die // remove it to execute the query
return $query->get()->toArray();
}

Resources