How to alias table in Laravel using newQuery() - php

I have a table with the name cotacaoitensfranqueado and I'd like to call it using just cif, I know I can do this DB::table('cotacaoitensfranqueado as cif') how I saw in this question, but I'd like to do that using my model.
$user = Auth::user();
$model_cotacaoitensfranqueado = new Cotacaoitensfranqueado();
$query = $model_cotacaoitensfranqueado->newQuery();
$query->select('cotacaoitensfranqueado.*', 'c.status');
$query->join('cotacao as c', [
['c.codigoconcentrador', 'cotacaoitensfranqueado.codigoconcentrador'],
['c.codigoempresa', 'cotacaoitensfranqueado.codigoempresa'],
['c.codigocotacao', 'cotacaoitensfranqueado.codigocotacao'],
]);
$query->where('cotacaoitensfranqueado.codigoconcentrador', (int)$user->codigoconcentrador)
->where('cotacaoitensfranqueado.codigoempresa', (int)$codigoempresa)
->where('cotacaoitensfranqueado.codigofilial', $user->codigofilial)
->where('cotacaoitensfranqueado.codigocotacao', (int)$codigocotacao)
->where('c.status', 'A');
$cotacao = $query->get();

You don't need to use newQuery() or (int) with Eloquent:
Cotacaoitensfranqueado::where('codigoconcentrador', auth()->user()->codigoconcentrador)->get();
But if you really want to use it, use query() instead because newQuery() is deprecated.

I realize how to solve the problem, you can do the alias in the model
Cotacaoitensfranqueado.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Cotacaoitensfranqueado extends Model
{
protected $table = 'cotacaoitensfranqueado as cif';
public $timestamps = false;
}
Controller/CotacaoController.php
...
use App\Cotacaoitensfranqueado;
class CotacaoController extends Controller
{
...
public function canSendBuy($codigoempresa, $codigocotacao){
$user = Auth::user();
$model_cotacaoitensfranqueado = new Cotacaoitensfranqueado();
$query = $model_cotacaoitensfranqueado->query();
$query->select('cif.*', 'c.status');
$query->join('cotacao as c', [
['c.codigoconcentrador', 'cif.codigoconcentrador'],
['c.codigoempresa', 'cif.codigoempresa'],
['c.codigocotacao', 'cif.codigocotacao'],
]);
$query->where('cif.codigoconcentrador', (int)$user->codigoconcentrador)
->where('cif.codigoempresa', (int)$codigoempresa)
->where('cif.codigofilial', $user->codigofilial)
->where('cif.codigocotacao', (int)$codigocotacao)
->where('c.status', 'A');
$cotacao = $query->get();
dd($cotacao);
}
...
}

Related

Laravel Pagination not working after setConnection() on eloquent model

I have tried to create a model in Laravel 8.x that can use different databases (Dynamically). It is currently working by setting the connection after creating an instance of the model, using Laravels build-in "setConnection" function. However, pagination on the model is not working. I get the following error:
(PDOException(code: 42S02): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.times' doesn't exist
The problem is that the "test" database, is not the one I am currently telling the model to connect to. I am connectin to 'mysql_timer'. Is pagination reseting the DB connection to default or?
You can see my controller code here:
public function getStats(Request $request)
{
$query = new Time;
$query->setConnection('mysql_timer');
$query = $query->with(['user']);
$data = $query->paginate($length);
dd($data);
}
And my "Time" model:
class Time extends Model
{
use HasFactory;
protected $table = 'times';
public $timestamps = false;
protected $primaryKey = 'uid';
protected $fillable = [
'uid',
'mapid',
'runid',
'mode',
'style',
'rectime',
'recdate',
'strf_num',
'jump_num'
];
public function user()
{
return $this->hasOne(User::class, 'uid', 'uid');
}
}
You can use on($connection) to begin querying the model on a given connection:
$data = Time::on('mysql_timer')->with(['user'])->paginate($length);
public function getStats(Request $request)
{
$query = DB::table("mysql_timer.times as times)
->join("users", "users.id", "=", "times.user_id")
->paginate($length);
dd($query);
}
did u try like that?
First make model
php artisan make:time
After go model
protected $connection = "mysql_timer";
protected $table = "times";
protected $guarded = [];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
After go controller
$query = Time::query()->with("user")->paginate($length);
dd($query);

codeigniter 4, update model

I connected my codeigniter app with mysql. I created a table model like that:
<?php namespace App\Models;
use CodeIgniter\Model;
class UserModel extends Model{
protected $table = 'I_user';
protected $allowedFields = ['email', 'password','active', 'hash'];
}
And now in my Controller, I want to update user by changing email for example. How to do that?
My controller:
<?php namespace App\Controllers;
use App\Models\UserModel;
class Confirm extends BaseController
{
public function index($email, $hash)
{
if(!isset($email) || !isset($hash)){
return redirect()->to('/');
}
$model = new UserModel();
$user = $model->where('email', $email)->first();
if($user['hash'] == $hash){
// update $user email..
??
}
}
}
You can do it in such way:
$model->where('email', $user['email'])->set(['email' => 'YourNewEmailAddress'])->update();
or
$model->update(['email'=> $user['email']], ['email' => 'YourNewEmailAddress']);
You could use update directly to the model data
$data = [
'email' => 'Yourupdatedemailhere'
];
$model->update($user['email'], $data);
If the Primary key is not "id" in your data-table, then you need to mention that in your Model.
protected $primaryKey = 'email';
Then use:
$model->update(['email'=> $user['email']], ['email' => 'newemail#example.com']);

Trying to fill the intermediate table using attach() but getting "Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::attach()"

I have tables called users, places and user_place. users has a column called id that contains the id of the user and places has a column called place_id as well. The user_place table has 2 columns called user_id and place_id and I'm trying to automatically populate them with the corresponding ids. I read I have to use attach() function after setting up the relationships which I believe I have done but I might be wrong. Here they are:
class PlaceController extends Controller
{
public function likePlace(Request $request){
$placeId = $request['placeId'];
$userId = $request['userId'];
$user = User::where('id', $userId)->first();
$place = new Place();
$place->place_id = $placeId;
$place->save();
$user->places()->attach($place);
}
}
User model:
class User extends \Eloquent implements Authenticatable
{
use AuthenticableTrait;
public function places(){
return $this->hasMany('App\Place');
}
}
Place mode:
class Place extends Model
{
public function user(){
return $this->belongsToMany('App\User');
}
}
In a Many to Many relationship, you should define both relationships like the following:
User.php
class User extends \Eloquent implements Authenticatable
{
use AuthenticableTrait;
public function places()
{
return $this->belongsToMany('App\Place', 'user_place', 'user_id', 'place_id');
} // ^^^^^^^^^^^^
}
Note: Given that your intermetiate table name doesn't follow the naming convention we specified so Laravel knows where table to look up.
Place.php
Notice that you mentioned that the primmary key of your Place model is place_id, and this also scapes from the Laravel convention you should specify it:
protected $primaryKey = 'place_id'; // <----
class Place extends Model
{
public function user()
{
return $this->belongsToMany('App\User', 'user_place', 'place_id', 'user_id');
}
}
So now in your controller:
class PlaceController extends Controller
{
public function likePlace(Request $request)
{
$placeId = $request['placeId'];
$userId = $request['userId'];
$user = User::where('id', $userId)->first();
$place = new Place();
$place->place_id = $placeId;
$place->save();
$user->places()->attach($place);
}
}
Side note
As I side note, you could save a couple of line replacing some sentences with their equivalent:
$userId = $request['userId'];
$user = User::where('id', $userId)->first();
Using the find() method, this is equal to:
$user = User::find($request['userId']);
Then, you could create your related object using the static method create of an Eloquent model so this:
$placeId = $request['placeId'];
$place = new Place();
$place->place_id = $placeId;
$place->save();
Is equal to this:
$place = Place::create(['place_id' => $request['placeId']]);
Then your controller will be reduced to this:
class PlaceController extends Controller
{
public function likePlace(Request $request)
{
$user = User::find($request['userId']);
$place = Place::create(['place_id' => $request['placeId']]);
$user->places()->attach($place);
}
}

How to dynamically set table name in Eloquent Model

I am new to Laravel. I am trying to use Eloquent Model to access data in DB.
I have tables that shares similarities such as table name.
So I want to use one Model to access several tables in DB like below but without luck.
Is there any way to set table name dynamically?
Any suggestion or advice would be appreciated. Thank you in advance.
Model:
class ProductLog extends Model
{
public $timestamps = false;
public function __construct($type = null) {
parent::__construct();
$this->setTable($type);
}
}
Controller:
public function index($type, $id) {
$productLog = new ProductLog($type);
$contents = $productLog::all();
return response($contents, 200);
}
Solution For those who suffer from same problem:
I was able to change table name by the way #Mahdi Younesi suggested.
And I was able to add where conditions by like below
$productLog = new ProductLog;
$productLog->setTable('LogEmail');
$logInstance = $productLog->where('origin_id', $carrier_id)
->where('origin_type', 2);
The following trait allows for passing on the table name during hydration.
trait BindsDynamically
{
protected $connection = null;
protected $table = null;
public function bind(string $connection, string $table)
{
$this->setConnection($connection);
$this->setTable($table);
}
public function newInstance($attributes = [], $exists = false)
{
// Overridden in order to allow for late table binding.
$model = parent::newInstance($attributes, $exists);
$model->setTable($this->table);
return $model;
}
}
Here is how to use it:
class ProductLog extends Model
{
use BindsDynamically;
}
Call the method on instance like this:
public function index()
{
$productLog = new ProductLog;
$productLog->setTable('anotherTableName');
$productLog->get(); // select * from anotherTableName
$productLog->myTestProp = 'test';
$productLog->save(); // now saves into anotherTableName
}
I created a package for this: Laravel Dynamic Model
Feel free to use it:
https://github.com/laracraft-tech/laravel-dynamic-model
This basically allows you to do something like this:
$foo = App::make(DynamicModel::class, ['table_name' => 'foo']);
$foo->create([
'col1' => 'asdf',
'col2' => 123
]);
$faz = App::make(DynamicModel::class, ['table_name' => 'faz']);
$faz->create([...]);

Show data from 2 tables in laravel 5.4

I have a simple code, and now I want to select data from 2 tables. Then I want to show in my view. Here's my code
model:
Tikpro.php
class Tikpro extends Model {
public $table = "TIKPRO";
public $primaryKey = "ID_TIKPRO";
public function permintaan() {
return $this->hasMany('Permintaan', 'TIKPRO_ID', 'ID_TIKPRO');
}
model:
Permintaan.php
class Permintaan extends Model {
public $table = "PERMINTAAN";
public $fillable = array(
'NOMOR_TICKET',
'TGL_PERMINTAAN',
'NAMA_REQUESTER',
'BARANG_PERMINTAAN',
'NO_FPBJ',
'TGL_INPUT_FPBJ',
'TARGET_SELESAI',
'KETERANGAN',
'TINDAK_LANJUT_AKHIR',
'STATUS',
'FPB',
'RFQ',
'DO',
'BAST',
'TGL_DEADLINE',
'titik_proses',
'TIKPRO_ID',
);
public $primaryKey = "ID_PERMINTAAN";
public function tikpro() {
return $this->belongsTo('Tikpro','TIKPRO_ID','ID_TIKPRO');
}
Controller:
PermintaanController.php
public function details($ID_PERMINTAAN) {
$query = DB::table('PERMINTAAN')->select('TIKPRO.NAMA_TIKPRO')->join('TIKPRO','TIKPRO.ID_TIKPRO','=','PERMINTAAN.TIKPRO_ID')->get('all');
$jebret = Permintaan::find($ID_PERMINTAAN);
return view('permintaan.details', compact('jebret'))->with($query);
}
And how can I show it? In my view I try {{ $jebret->$query }} . But still can't show the data.
How should I write code? Thanks
I think you can try this
public function details($ID_PERMINTAAN) {
$query = DB::table('PERMINTAAN')->select('TIKPRO.NAMA_TIKPRO')->join('TIKPRO','TIKPRO.ID_TIKPRO','=','PERMINTAAN.TIKPRO_ID')->where('PERMINTAAN.ID_PERMINTAAN',$ID_PERMINTAAN)->get();
return view('permintaan.details', compact('query'));
}
Hope this work for you
There's 2 ways here. The first and easiest (if you've set it up correctly) is the relationship. https://laravel.com/docs/5.4/eloquent-relationships. To use the one in your example you want to do this:
$permintaans = Permintaan::query()->get()->all();
return view('permintaan.details', [
'permintaans' => $permintaans,
]);
//In the view
#foreach($permintaans as $permintaan)
<tr>{{$permintaan->tikpro->attribute}}</tr>
#endforeach
Another way like you've attempted is the join. In the select though I would leave it blank so you get all columns!
$permintaans = Permintaan::query()
->join('TIKPRO','TIKPRO.ID_TIKPRO','=','PERMINTAAN.TIKPRO_ID')
->get()
->all();

Categories