Disable timestamps in Laravel model - mysql

I have simple model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserExt extends Model
{
protected $table = 'users_ext';
public $timestamps = false;
}
In controller i try to display some data from users_ext in controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Illuminate\Support\Facades\Auth;
use App\UserExt;
class RegisterController extends Controller
{
public function registerCheck(Request $request){
$user_ext=UserExt::latest()->get();
return response()->json(array(
'users'=>$user_ext,
));
}
}
But i got an error with:
Column not found: 1054 Unknown column 'created_at' in 'order clause' (SQL: select * from users_ext order by created_at desc)
I thought, $timestamps=false will disable managing timestamp by Eloquent.
Do i have to do something else?

Would you mind showing your scopeLatest method in your model? I think the problem lie there, probably orderBy set to created at.

Related

Query builder don't accept onlyTrashed()

I'm a beginner and cant find a solution to my problem. I trying to get "onlyTrashed" from my DB but Laravel 8 don't accept my query commands :( I tried many scenarios but unsuccessful.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\Category;
class CategoryController extends Controller{
public function AllCat(){
$categories = $trashCat = DB::table('categories')
->join('users','categories.user_id','users.id')
->select('categories.*','users.name')
->latest()
->paginate(5);
//$categories = Category::latest()->paginate(5);
// $trashCat = Category::onlyTrashed()->latest()->paginate(3);
return view('admin.category.index', compact('trashCat','categories'));
public function SoftDelete($id){
$delete = Category::find($id);`enter code here`
return Redirect()->back()->wiht('success',' Category Delete Successfuly');
Route::get('/softdelete/category/{id}', [CategoryController::class,'SoftDelete']);
Please make sure that your model imports and uses SoftDeletes trait to implement soft delete in your model and make sure that your table has deleted_at field, your model may look like below codes.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Category extends Model
{
use SoftDeletes;
And in your SoftDelete function within the controller, I think you miss delete() function, your function should look like:
public function SoftDelete($id) {
$delete = Category::find($id)->delete();
return redirect()->back()->with('success',' Category Delete Successfully');
}
Once you implement SoftDeletes trait into your model, delete() function should mark deleted by filling the deleted_at with timestamp or DateTime automatically. Once you implement the above codes, onlyTrashed() should work.
$categories = Category::latest()->paginate(5);
$trashCat = Category::onlyTrashed()->latest()->paginate(3);

Sort the parent model based on the child model / relationship

I have a model called appointments, each appointment has an option_id that is linked through a one to one relationship and the option_id can also be null. The option model has a property datetime_start. I want to sort the appointments based on the option.datetime_start.
Here is my code :
$appointments = $user->appointments()
->with(['option'
])
->get();
Edit :
Appointment model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Appointment extends Model
{
/**
* #return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function option()
{
return $this->hasOne(Option::class, 'id', 'option_id');
}
}
Option model :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Option extends Model
{
protected $fillable = ["appointment_id",
"datetime_start"
];
public function appointment()
{
return $this->belongsTo(Appointment::class, 'id','appointment_id');
}
}
Any help would be greatly appreciated.
In order to sort Appointment model by a column from related Option model, you need to add a JOIN to your query so that you can sort by related fields:
$appointments = $user->appointments()
->leftJoin('options', 'options.appointment_id', '=', 'appointments.id')
->orderBy('options.datetime_start', 'ASC')
->with(['option'])
->get();
This will give you all appointments, including those without Option - the ones without an Option and, hence, without datetime_start, will be all returned either at the beginning or the end of the result list, you'll need to check that. If you only want appointments with Option, replace leftJoin() with join().
$appointments = Appointment::with(['option' => function ($query){ $query->orderBy('datetime_start', 'desc'); } ])->get();

And Where is not working before where condition?

Here I am overriding the find() method
class ActiveRecord extends BaseActiveRecord{
public static function find() {
return parent::find()
->where(['=',static::tableName().'.company_id',Yii::$app->user->identity->company_id])
->andWhere(['=',static::tableName().'.branch_id',Yii::$app->user->identity->branch_id]);
}
}
Now if I use the condition like this
\common\models\Order::find()->where(['stastus'=>'3'])->count();
the Active Record global condition is executed before the condition I am
using in Order model and after that the Order Model where overriding
the active record global condition.
And if I use the Active Record condition like this
class ActiveRecord extends BaseActiveRecord{
public static function find() {
return parent::find()
->andWhere(['=',static::tableName().'.company_id',Yii::$app->user->identity->company_id])
->andWhere(['=',static::tableName().'.branch_id',Yii::$app->user->identity->branch_id]);
}
}
There were in my local model overriding the global condition. Difficult for
me to override each where with and where.
You should change the where and andWhere to onCondition in your BaseActiveRecord which I suppose is an alias for \yii\db\ActiveRecord as the parent::find() return object of ActiveQuery if you look into the find() method it returns below line
\yii\db\ActiveRecord
return Yii::createObject(ActiveQuery::className(), [get_called_class()]);
you can see here customizing-query-class to add an extra condition
class ActiveRecord extends BaseActiveRecord{
return parent::find ()
->onCondition ( [ 'and' ,
[ '=' , static::tableName () . '.application_id' , 1 ] ,
[ '=' , static::tableName () . '.branch_id' , 2 ]
] );
}
Now if you call
\common\models\Order::find()->where(['status'=>'3'])->createCommand()->rawSql;
it will generate the following query
SELECT * FROM `order`
WHERE (`status` = 3)
AND
((`order`.`application_id` = 1) AND (`order`.`branch_id` = 2))
This is the way how the Yii2 ActiveRecord works. When you call method where() it reset conditions, even if was not empty and when you call andWhere() it add new condition to existing ones.

Want to get maximal value, but query doesn't work

I try to program a query in Yii2, which shows me the highest value of the database. Unfortunately, I get error message:
"Call to a member function all() on string"
How to patch this problem?
<?php
namespace app\controllers;
use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;
class CountryController extends Controller
{
public function actionIndex()
{
$query = Country::find();
$countries = $query->select('population')->max('population')
->all();
return $this->render('index', [
'countries' => $countries,
]);
}
}
?>
You can use this
$query = Country::find();
$countries = $query->select('population')->max('population');
Also you can use
$query = Country::find();
$countries=$query->select('max(population) as `population`')->one();
It will help you :)
You have put as 'population' or other field name in table to assign value in second query.
According to your code example, you are calling all() on the result of max(), which according to the error message is returning a string.
max() is returning the maximum value, so you probably just need to drop ... ->all().
Try this:
$countries = $query->select('population')->max('population');

CakeDC Search plugin doesn't work

i'm trying to develop a simple search form using cakedc plugin, i followed step by step the instructions , but i got the next error:
Database 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 'validateSearch' at line 1
SQL Query: validateSearch
i don't know what i got wrong, can you help me?, this is what i've got, Thank you.
In the Controller:
class ProductosController extends AppController {
public $name = 'Productos';
public $uses = array('Empleado','Cliente', 'Mesa','Producto', 'Productotipo','Productos');
public $components = array('Search.Prg');
public $presetVars = true;
public $paginate=array();
public function ventas(){
$this->Prg->commonProcess();
$this->paginate['conditions'] = $this->Producto->parseCriteria($this->Prg->parsedParams());
$this->set('productos', $this->paginate());
}
In the Model:
class Producto extends AppModel {
public $name = 'Producto';
public $displayField = 'productotipos_id';
public $belongsTo = array('Productotipo'=>array('className'=>'Productotipo','foreignKey'=>'productotipos_id','conditions'=>'','order'=>''));
public $actsAs = array('Search.Searchable');
public $filterArgs = array(
'nombre' => array('type' => 'like')
);
In the view
<?php echo $this->Form->create('Producto', array('url' => array_merge(array('action'=>'ventas'), $this->params['pass'])));?>
<fieldset>
<legend>Pedido</legend>
<?php
echo $this->Form->input('Producto.nombre', array('div'=>false, 'empty'=>true));
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();
?>
</fieldset>
Try to reorder $uses that Controller's model will be the first:
public $uses = array('Producto', 'Empleado', 'Cliente', 'Mesa', 'Productotipo');
Should help. Don't know why, but probably some of methods from CakeDC Search plugin depends on first item in this array.
SQL Query: validateSearch
Is the usual error when you try to call a model method that does not exist.
So whatever model you try to paginate (it was not a good idea to not paste the class declarations...) does not use the searchable behavior for some reason.
In the case the model is the correct one the behavior is not loaded for some reason that you'll have to figure out.