Eloquent model cannot select from MySQL view - mysql

Has MySQL view 'histstat'.
In MySQL select * from histstat works fine.
Laravel model is very simple:
class HistStat extends Model
{
use HasFactory;
protected $table = 'histstat';
protected $fillable = ['day', 'total', 'paid'];
}
Then I want to get first 14 records of hisstat:
$dynamic = HistStat::all()->slice(14);
... and execution ends with error SQLSTATE[42000]: Syntax error or access violation: 1055 (SQL: select * from 'histstat')
When I try to use table-based model ($dynamic = History::all()->slice(14);) - everything works fine.
So, the problem in MySQL view + Laravel.
How to use view-based model in Laravel ?

For the SQL error,
In config\database.php in "mysql" array
Set 'strict' => false
I think this one will help Laravel: Syntax error or access violation: 1055 Error.
For the first 14 records, you can do it
HistStat::oldest()->take(14)->get();
better than all() because I do not recommend using it if you have a huge table that will be load on the server because all() get all records select * from "users"

In config/datatable.php (mysql section):
Change strict to false
Add / change in options - PDO::ATTR_EMULATE_PREPARES => true

Related

Can't delete a collection of Laravel eloquent

I am retrieving a collection from db and want to delete it. This is the code.
$signal_id = $request->del_signal_id;
$signal_details = VwDistressSignals::where('signal_id', $signal_id)->delete();
return "Success";
}
And this is the error.
message: "SQLSTATE[HY000]: General error: 1395 Can not delete from join view 'dvp.vw_distresssignals' (SQL: delete from `vw_distresssignals` where `signal_id` = 2)"
I have also tried giving all the column names. This is the model...
<?php
namespace App\Models;
use Reliese\Database\Eloquent\Model as Eloquent;
class VwDistressSignals extends Eloquent
{
protected $table = 'vw_distresssignals';
}
This error is happening because your relationship is not properly defined.
Delete with the loop
$signal_id = $request->del_signal_id;
$signal_details = VwDistressSignals::where('signal_id', $signal_id)->get();
foreach($signal_details as $detail)
{
$detail->delete();
}
return "Success";
Since you haven't shared your model, I assume it corresponds to a database view rather than a table.
If so try deleting from the base table(s) as join views are not deletable.
DELETE ... Join views are not allowed.
https://dev.mysql.com/doc/refman/5.7/en/view-updatability.html

SQLSTATE[42000]: Syntax error or access violation: 1055 when using groupBy with hasManyThrough relation in Laravel

When using groupBy on hasMany relation it is work fine but
when using groupBy on hasManythrough relation
in my controllr :
public function main()
{
# code...
$user = Auth::user();
$results = [
'vacations' => $user->vacations()->groupBy('type')->selectRaw('sum(days) as days,sum(mins) as mins, type')->get(), //works fine
'vactionRegisterd' => $user->vacationsRegisterd()->groupBy('type')->selectRaw('sum(days) as days,sum(mins) as mins, type')->get(), //works fine
'empVacations'=>$user->empVacations, //work fine
'employees_vacations'=>$user->empVacations()->groupBy('type')->selectRaw('sum(days) as days,sum(mins) as mins, type')->get(),//gives an error
];
return view('dashboard.dashboard', ['results' => $results]);
}
I have this error :
SQLSTATE[42000]: Syntax error or access violation: 1055
'hrweb.users.manager_id' isn't in GROUP BY (SQL: select sum(days) as
days,sum(mins) as mins, type, users.manager_id as
laravel_through_key from vacations inner join users on
users.id = vacations.user_num where users.manager_id = 5
group by type)I have tow tables users ,vacations
I don't know why (users.manager_id as laravel through key) is used even though I didn't use "users.manager_id" with "groupBy" or "selectRow" method.
My Code in user model :
1- user has many employees where employees are also users with different role and with manager_id != null [user->employees]
/**
* Get all of the employees from user table for the current admin User
*/
public function employees()
{
return $this->hasMany('App\Models\User', 'manager_id');
}
2- user has many vacations [user->vacations]
/**
* Get all of the vacations for the User
*/
public function vacations()
{
return $this->hasMany('App\Models\Vacations', 'user_num', 'id');
}
3- user hasManyThrough vacations [user->employees->vacation]
/**
* Get all of the employees vacations for the User
*/
public function empVacations()
{
return $this->hasManyThrough(Vacations::class, User::class, 'manager_id', 'user_num', 'id', 'id');
}
By reading the Error again ,I noted that Laravel use the foreign key as laravel_through_key in the query in some way.
The problem solved by adding laravel_through_key in the groupBy() method like this :
[...
'employees_vacations'=>$user->empVacations()
-> groupBy('laravel_through_key','user_num','type')
-> selectRaw('sum(days) as days,sum(mins) as mins,user_num, type')->get()
]
But I still think there is a better solution so I will be happy to know your answers ^_^

cakephp 3 (My)SQL aggregate function max() syntax error near 'AS MAX(`users`__`date_time`) AS `date`

I'm developing a social application with cakephp 3.
I'm working on the messanging function right now. It works this way, that on the left side one gets displayed the users, who one has conversations with and in the middle is the conversation.
I want the users to be sorted by last messaging date. Meaning, if Peter was the last one I wrote to, then Peter should appear on top and so on.
I have the following query:
$query = $this->Messages
->find('all', [
'fields' => [
'MAX(`messages`.`max_date`)',
'id',
'sender_id',
'reciever_id',
]
])
->where([
'sender_id = ' => $active_user_id
])
->orWhere([
'reciever_id = ' => $active_user_id
])
->group([
'sender_id',
'reciever_id'
])
->order([
'id' => 'DESC'
]);
For performance reasons I added a grouping by sender_id and reciever_id, since I don't want to recieve all messages, but only find the users, that I wrote with so far.
The problem is that the group-statement destroys the sorting. So I thought about a max-aggregate-function to preserve the order.
However I get the following error-message by the cakephp framework:
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MAX(`messages`__`max_date`), Messages.id AS `Messages__id`, Messages.sender_id A' at line 1
So does anyone know, what is wrong with my query? I gave my best to follow the example in the documentation.
Why does it say messages__max_date and not messages.max_date?
That's simply not how you define computed fields and correspondig alias, this needs to be done in a key => value fashion, ie
'fields' => [
'max_date' => 'MAX(`Messages`.`date_time`)',
// ...
]
which would result in an SQL fragment like
MAX(`Messages`.`date_time`) AS `max_date`
See Cookbook > Database Access & ORM > Query Builder > Selecting Data
Also as a tip, you might want to use expressions instead of simple strings, so that CakePHP can properly create platform specific SQL in case required. MAX isn't affected AFAIR, so this is just a general hint.
$query = $this->Messages->find();
$query
->select([
'max_date' => $query->func()->max($this->Messages->aliasField('date_time'))
// ...
])
// ...
See Cookbook > Database Access & ORM > Query Builder > Using SQL Functions

CakePHP SQL Error when trying to use loadModel

I have two controllers (Feeds & Items), on the Items add view, I want some information from the Feeds table visible to the user.
So in the Items Controller I'm trying to access the Feed model, everything I have come across recommends to use loadModel but when I try to load the Items add view, I getting the following error:
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
SQL Query: SHOW TABLES FROM
Please note there is no relationship setup between these two tables.
Feed Model
App::uses('AppModel', 'Model');
class Feed extends AppModel {}
Item Model
App::uses('AppModel', 'Model');
class Item extends AppModel {}
Item Controller
App::uses('Feed','Model');
class ItemsController extends DirectResponseAppController {
function add() {
if ($this->request->is('post')) {
$this->Item->create();
if ($this->Item->save($this->request->data)) {
$this->Session->setFlash(__('Your item has been saved.'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to add your item.'));
} else {
$this->loadModel('Feed');
$xxx = $this->Feed->find('all');
}
}
}
Any help appreciated.
** EDIT **
After a bit more digging, the problem seems to be with this line:
$xxx = $this->Feed->find('all');
I'm just not sure why.
If your Feed is inside a plugin (DirectResponse), you must use loadModel like this:
$this->loadModel('DirectResponse.Feed');

CakePhp mysql raw query error

I'm new to cakephp. I'm trying to search through mysql tables. I want to use nested query.
class TableController extends AppController{
.
.
public function show(){
$this->set('discouns', $this->DiscounsController->query("SELECT * FROM discoun as Discoun WHERE gcil_id = 1"));//(SELECT id FROM gcils WHERE genre = 'Shoes' AND company_name = 'Adidas')"));
}
}
Error:
Error: Call to a member function query() on a non-object
I've also tried
public function show(){
$this->DiscounsController->query("SELECT * FROM count as Count WHERE ctr_id = (SELECT id FROM ctrs WHERE genre = 'Shoes' AND company_name = 'Adidas')");
}
Error:
Error: Call to a member function query() on a non-object
File: C:\xampp\htdocs\cakephppro\myapp\Controller\CountsController.php
Please help. I've been trying this for last few hours. :/
As mentioned in the comments there are a few problems with your code.
Firstly, you are trying to call the query() method on a Controller, whereas you should be executing it on a Model, as it is models that handle database queries and the controller should simply be used to call these methods to get the data and pass them to the view.
The second thing is that you are executing a very simple SQL query raw instead of using CakePHPs built in functions <- Be sure to read this page in full.
Now for your problem, as long as you have setup your model relationships correctly and followed the correct naming conventions, this should be your code to run your SQL query from that controller:
public function show(){
$this->set('discouns', $this->Discouns->find('all', array(
'conditions' => array(
'gcil_id' => 1,
'genre' => 'shoes',
'company_name' => 'Adidas'
)
));
}
query() is not a Controller, but a Model method. That's what the error (Call to a member function on a non-object) is trying to tell you.
So the correct call would be:
$this->Discount->query()
But you are calling this in a TableController, so unless Table and Discount have some type of relationship, you won't be able to call query().
If the Table does have a relationship defined you will be able to call:
$this->Table->Discount->query()
Please not that query() is only used when performing complex SQL queries in scenarios where the standard methods (find, save, delete, etc.) are less practical.
$this->Counts->find('all',array(
'conditions' => array(
'ctrs.genre' => 'Shoes',
'ctrs.company_name' => 'Adidas'
), 'recursive' => 1
));
The above is with tables named counts and ctrs.
This is assuming you have the model set up to have some sort of relationship between the counts table and the ctrs table. It's kind of hard to tell in your code exactly what you tables are.
The CakePHP book should have all the answers you need. One of the reasons to run CakePHP over regular PHP is the FIND statement. Once you have your models set up correctly, using the find statement should be really easy.
http://book.cakephp.org/2.0/en/models.html