How to call a function inside eloquent Model directly without query? - php

I have function showItemList inside User class
class User extends Eloquent {
//...
protected $item = ['axe', 'sword', 'knife'];
public function showItemList() {
return $this->$item;
}
}
In my controller it's possible to use this.
$id = 1;
$user = User::find($id);
$user -> showItemList();
But how can I just call this function directly(irrelevant to $id query)?
I looks for something like below (sure now it's not working):
$list = User::showItemList();

You need to use the static protected variable and return it from static method.
class User extends Eloquent {
//...
static protected $item = ['axe', 'sword', 'knife'];
public static function showItemList() {
return self::$item;
}
}

Related

Eloquent select using the wrong class?

Context: Trying to extend Laravel models from a database table. Table models linked to App\Models\BootableModel, App\Models\User extends this class.
I have the following code:
<?php
class BootableModel extends Model
{
protected $table = 'models';
protected $fillable = [
'name',
'class',
'table',
];
public function __construct(array $attributes = [])
{
$this->bootFromDatabase();
parent::__construct($attributes);
}
private function bootFromDatabase()
{
$class = static::class;
$bModClass = self::class;
Log::debug($class);
Log::debug($bModClass);
//$bootableModel = DB::table('models')->where('class', $class)->first();
$bootableModel = $bModClass::where('class', $class)->first();
if(!$bootableModel) {
return;
}
Log::debug($bootableModel->id);
The debug of $bModClass shows App\Models\BootableModel as expected (self vs static), but for some reason the $bModClass::where is trying to query the users table. Using a direct reference to App\Models\BootableModel::class does not change this, so it's not self::class that is the issue. The debug output as proof:
[2021-02-21 17:33:39] local.DEBUG: App\Models\User
[2021-02-21 17:33:39] local.DEBUG: App\Models\BootableModel
It should never try to access User::where(), and as such, it should never try to use User::$table either, but somehow it does.
Is Laravel doing some weird reflection, or is this normal PHP behavior? Is there a way around this?
Update:
I have found a workaround, but I'm not satisfied with this being the correct/only solution:
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
static::bootFromDatabase();
}
public static function bootFromDatabase()
{
$class = static::class;
$bModClass = self::class;
if($class === $bModClass) {
return;
}
Have you ever tried self::where(...) instead of $bModClass::where(...) ?
Similar situation:
class Base {
public static function where()
{
return 'where from base';
}
public static function getName()
{
return self::where();
}
}
class User extends Base {
public static function where()
{
return 'where from user';
}
}
echo User::getName();
Output: where from base

How Pass variable from Controllers to Model

I want to pass $id from my Controllers to Model, please help me
this my Controllers
class OrderController extends Controller
{
public function show($id,Request $request) {
$data= order_list::select('*')
->where('t_order_list.id_order', $id)
->get();
}
}
how to pass $id to my model
class order_list extends Model
{
protected $table = "t_order_list";
protected $fillable = ['id_order','id_product','id_variant','qty_order'];
protected $with = ['variant_list'];
public function variant_list($id){
return $this->hasMany('App\Model\variant','id','id_variant')
->join('t_color','t_variant.id_pcolor','=','t_color.id')
->join('t_size','t_variant.id_psize','=','t_size.id')
->join('t_subcategory','t_variant.id_pcategory_sub','=','t_subcategory.id')
->join('t_order_list as d', 't_variant.id', '=', 'd.id_variant')
->select(['t_variant.*','t_color.code_pcolor','t_size.code_psize','t_color.hex_pcolor'
,'t_color.hex_pcolor_2','t_color.hex_pcolor_3',
't_subcategory.name_pcategory_sub','d.qty_order'])
->where('d.id_order', $id);
}
this my error
Call from Controller like OrderList::variant_list($id) and define function like
public static function variant_list($id){
return $this->hasMany('App\Model\variant','id','id_variant')
->join('t_color','t_variant.id_color','=','t_color.id')
->join('t_size','t_variant.id_size','=','t_size.id')
->join('t_subcategory','t_variant.id_subcategory','=','t_subcategory.id')
->join('t_order_list as d', 't_variant.id', '=', 'd.id_variant')
->select(['t_variant.*','t_color.code_color','t_size.code_size','t_color.hex_color'
,'t_color.hex_color_2','t_color.hex_color_3',
't_subcategory.name_subcategory','d.qty_order']);
}
You can pass simply the variable from controller to models.
For Normal method:-
Controller:-UserController
public function test(){
$id = "A";
$user = new User; //create object
$user->passValue($id);
}
Model:- User
public function passValue($id){
echo $id;
}
For Static method:-
public function test(){
$id = "A";
User::passValue($id);
}
Model:- User
public static function passValue($id){
echo $id;
}

Is it necessary creating a function in model when updating database

I have a controller like this
use App\Model\User;
class UserController extends BaseController
{
protected $model;
public function __construct(User $user)
{
$this->model = $user;
}
public function updatePhone(Request $request)
{
//user id
$id = $request->id;
//new phone number
$phone = $request->phone;
}
}
The function updatePhone is used to update the phone number of the user.So I can code like this
$res = $this->model->where('id',$id)->update('phone',$phone)
In this way, I do nothing in the user model.But I get used to like this
$res = $this->model->updatePhone($id, $phone);
And I must create function updatePhone in user model
public function updatePhone($id,$phone)
{
return $this->where('id',$id)->update('phone',$phone);
}
who is the better way to update a single model? Any answers or suggestions are excepted.

Model Observer, not working for update?

Im having trouble trying to get my model observer to work.. It is working as expected for create and deleted, but not for updating. Im guessing the event never fires. The thing is all of then are being done exactly the same way. Any ideas?
Below, my observer.
class GenericObserver extends AbstractObserver {
protected $events;
public function __construct(Dispatcher $dispatcher){
$this->events = $dispatcher;
}
public function saved($model) {
dd($this->events);
$user_id = Auth::user()->usr_id;
$user_nome = Auth::user()->usr_nome;
$user_email = Auth::user()->usr_email;
dd($model);
}
public function deleted($model) {
$user_id = Auth::user()->usr_id;
$user_nome = Auth::user()->usr_nome;
$user_email = Auth::user()->usr_email;
echo($model->getTable());
dd($model->getKeyName());
}
public function updated($model) {
$user_id = Auth::user()->usr_id;
$user_nome = Auth::user()->usr_nome;
$user_email = Auth::user()->usr_email;
dd($model);
}
public function saving($model){
echo 'Saving';
}
public function deleting($model){
echo 'Deleting';
}
public function updating($model){
echo 'Updating';
}
And here, my model class
Aplicacao extends Model {
protected $table = 'gst_aplicacoes';
protected $primaryKey = 'app_id';
protected $fillable = ['app_nome', 'app_key', 'app_observacao'];
public static function table() {
$model = new static;
return $model->getTable();
}
public static function boot() {
parent::boot();
Aplicacao::observe(new GenericObserver(new Dispatcher));
}
If anyone ever faces this issue, the reason the event was not firing was because the update method, only fire its events when the update happens directly on the model, since i was using an intermediary repository to represent my model, it wasn't working.
for more details.
https://github.com/laravel/framework/issues/11777#issuecomment-170388067
Observer work on only save() method. And it's not working on function of query builder that you call by magic methods. So on update() and created() observer is not work.
This will work:
Model::find($id)->update(['column' => $value]);

Passing variables from Model to controller

I have variables that are created and used on my model that I need to be able to use on my controller how is that accomplished?
Edit:
Controller: http://pastebin.com/jhAwAVa6
Model: http://pastebin.com/9xXRyYAa
It's unclear from your question, what exactly you want to do.
If it is about accessing model properties, the right way is using accessor methods:
class Model extends CI_Model{
private $name;
public function getName() {return $this->name; /*any other logic here*/}
public function setName($value) {$this->name= $value; /*any other logic here*/}
}
You can not pass the variable from a model to controller.
You can access public variables of a model through a controller.
echo $this->model_name->variable_name;
Model (my_model)
function useful_info()
{
$data = new stdClass();
$q = $this->db->get('users');
$data->users = $this->db->result();
$data->date = date('Y-m-d');
$data->info = array('whatever','more','anything');
return $data;
}
Controller
function index()
{
$info = $this->my_model->useful_info();
foreach($info->users as $user)
{
echo $user->id;
}
echo $info->date;
if($info->info[0] == 'whatever')
{
// do something
}
}
You don't have to create an object (it can be a string, T/F, array, etc), but you usually need to return something from your model and library functions. And you can access what you return by returning it to a variable $info = $this->my_model->useful_info();

Categories