recently I am using PHP Laravel with PostgreSQL and I don't know how to convert this sql script to eloquent.
SELECT v_extensions.extension,
(
SELECT COUNT(v_xml_cdr.uuid) FROM v_xml_cdr WHERE v_xml_cdr.extension_uuid = v_extensions.extension_uuid AND start_stamp >= #startDate AND end_stamp <= #endDate
)
FROM v_extensions ORDER BY count DESC LIMIT 1
I am trying to do something like this, but I don't know how can I write that extension_uuid from XmlCdr is equal to extension from Extension. Also these columns are not linked by foreign key on database.
$call = Extension::select('extension', function(){
XmlCdr::where('extension_uuid', )
})->limit(10)->get();
found it a way how to do it with DB::select
$query = 'SELECT v_extensions.extension, (SELECT COUNT(v_xml_cdr.uuid) FROM v_xml_cdr WHERE v_xml_cdr.extension_uuid = v_extensions.extension_uuid) FROM v_extensions LIMIT 1';
$result = DB::select($query);
First, Eloquent is an ORM. To use it you'll have to create Model(s) which extend the Eloquent model model docs and define the relationships on them
relations docs
Assuming you did it, you should have something like this:
class ExtensionCDR extends \Illuminate\Database\Eloquent\Model
{
protected $primaryKey = "uuid"; // primary key column name
protected $table = "v_xml_cdr"; // by default Eloquent assumes your table has the same name as the class - more or less
// add relations like
public function extensions()
{
return $this->hasMany(Extensions::class); //further parameters may needed - see docs
}
}
class Extensions extends \Illuminate\Database\Eloquent\Model
{
protected $table = "v_extensions";
// add relations
}
With this you can do this (anywhere basically):
(I'm not sure about which table has the relevant timestamps)
// this is the case where the timestamps are on the related model
$result = ExtensionCDR::whereHas('extensions', function ($query) use($start, $end) {
return $query->whereDate('start_stamp', '>', $start)
->whereDate('start_stamp', '<', $end);
})->get();
I understand that this won't be a perfect (copy/pasta) answer, but I hope it will steer you in the right direction;
In case I misunderstood you completely, just use the Database module with raw queries like so: raw things
Related
I am using Laravel and sqlsrv, connected to SQL Server 2016 and all is working great until I try to use an output clause in my insert query.
Query is something like
INSERT INTO TABLE(Columns) OUTPUT INSERTED.MyDesiredReturnColumn VALUES(Value)
This is working perfectly in SQL Server, and returning the desired value, but using Laravel's DB::insert functionality it is only returning a 1 (for successful insert)
I have a workaround that I would rather not have right now, using the CreatedOn field to return the most recently created row, but this has potential issues.
UPDATES: The field I am attempting to retrieve is a uniqueidentifier field (guid) that is created in SQL, not from Laravel-side
After attempting #PrathameshPalav's recommendation of using the Eloquent model creation, the values are being inserted correctly into the DB, but it is not returning the uniqueidentifier still.
$inserted = MyModel::create($information);
print "inserted id is " . $inserted->MyModelId;
This is printing "inserted id is "
Here is my model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
//
protected $table = 'MyModelBase';
protected $primaryKey = 'MyModelId';
public $incrementing = false;
protected $keyType = "string";
public $timestamps = false;
protected $fillable = ['field1', 'field2', 'etc'];
}
Any ideas would be greatly helpful.
You can use Eloquent ORM for this purpose:
$insertedObject = ModelName::create($input_array);
It will return inserted model object in response. Or if you want only inserted record id then use
DB::table($tablename)->insertGetId($input_array);
The way that I solved this was by incorporating an Eloquent model (as pointed out by #PrathameshPalav), then (loosely) following this tutorial https://danielkoch.work/log/laravels-eloquent-guids.html
Specifically this part
public static function boot() {
parent::boot();
// Hook when a model is created
static::creating(function ($model) {
// Select a new ID
$result = DB::select( DB::raw('Select NewID() NewUUID') );
$model->{$model->getKeyName()} = $result[0]->NewUUID;
});
}
After that, I added the primary key I had defined to the $fillable array and tested, and it works =)
Thank you both for your help!
Yes, when you use insert it will return a bool. You can use insertGetId to get the the id.
If the table has an auto-incrementing id, use the insertGetId method
to insert a record and then retrieve the ID:
$data = [....]; // data that will be inserted
$id = DB::table('xxx')->insertGetId($data);
More info:
https://laravel.com/docs/5.5/queries#inserts
Is it possible to override the ->get() methods from Eloquent in order to always customize the output of the selected fields from the DB query?
For example, if you do a usual Eloquent query like:
User::where('email','like','%wherever.com')->get();
Instead of it making the query:
Select name, email, address, created_at from users where email like '%wherever.com'
Is it possible to override the method to always return something like:
Select CONCAT('CL::',name), lower(email), address, created_at from users where email like '%wherever.com'
I ask for ->get because I have seen that I can pass an array with the columns to be selected but I don't want to define them on all queries.
So, after digging around the functions regarding the query I found this solution:
I created a new class CustomQueryBuilder that extends the Illuminate\Database\Query\Builder
There you can override the get() / select() / where() methods from Eloquent.
Then, in the models that you want to change the way the query is made, define the fields to change like:
protected $encrypted = [
'name',
'email',
];
After this, I created a new class CustomModel that extends the Illuminate\Database\Eloquent\Model and there override the newBaseQueryBuilder like this:
protected function newBaseQueryBuilder()
{
$connection = $this->getConnection();
return new CustomQueryBuilder(
$connection, $connection->getQueryGrammar(), $connection->getPostProcessor(), $this
);
}
Inside the CustomQueryBuilder you can customise all the methods from builder for your needs.
With this setup, you can in any Illuminate\Database\Eloquent\Model change it to extend your CustomModel and inherit this special behaviour for the designated columns.
Be aware that all queries made from Models extending your CustomModel will get this new methods, so do all the needed checks to don't mess up with Eloquent normal behaviour, something like this:
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
if ($this->model !== null && isset($this->model::$encrypted))
{
if (in_array($column, $this->model::$encrypted))
{
$column = DB::raw("CONCAT('CL::',$column)");
}
}
parent::where($column, $operator, $value, $boolean);
}
PS: I know this sound silly with the CONCAT example but with the property $encrypted you can figure out that it's not for concatenating string.
You can use model to update the result for the specific field like below
Use this code in your model file to contact CL::' with thename` value
public function getNameAttribute($value) {
return 'CL::'.$value;
}
You can just call User::where('email','like','%wherever.com')->get(); like this
This getNameAttribute function will always return name value with "CL::"
So you don't need to add CONCAT('CL::'.name) with your query.
Same way you can add for other fields also
Updated
Solution when querying the result
Add this geofields in your model
protected $geofields = array("concat('CL::',name) as name");
Add this newQuery function to override the columns
public function newQuery($excludeDeleted = true)
{
$raw='';
foreach($this->geofields as $column){
$raw .= $column;
}
return parent::newQuery($excludeDeleted)->addSelect('*',\DB::raw($raw));
}
Hope this is what you expect.
im sory, im noob in laravel. later, im build web just use php native, and i have code like this
$query1 = select * from user where id='$id';
while($data1 = mysql_fetch_array($query1){
$query2 = select * from komen where iduser=$data['id'];
}
so to convert to laravel be what.
I already read the documentation laravel but did not find
Where id = $id should only return 1 value (given that id is your unique primary key), so you would never have to loop through the result of your $query1, it's just 1 or nothing.
Best thing you can do to fetch the related Komen is to setup a relation in the model. For more info see: https://laravel.com/docs/5.3/eloquent-relationships
Best option for you is to create the User model first (already exists after Laravel installation) and add the komens() relation (1:n)
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'user'; // should be users
// define has many relationship
public function komens()
{
// you will have to set userid, as laravel searches for user_id (singular tablename _ key)
return $this->hasMany(Komen::class, 'userid');
}
}
Then create the Komen model (check your naming conventions, laravel looks for the table name as the lowercase snake_cased plural version of your model name, so in this case komens. If you want to overwrite this, you have to set the protected $table = 'komen';
use Illuminate\Database\Eloquent\Model;
class Komen extends Model
{
protected $table = 'komen'; // should be komens
// define the inverse of the user model's komens() method
public function user()
{
return $this->belongsTo(User::class, 'userid');
}
}
Now in your code you can do something like this:
// fetch the user by id
$user = User::find($id);
// check if user exists
if ($user) {
// fetch all related komens from the database and loop through the collection
$user->komens->each(function($komen) {
// do foo here
dump($komen);
});
}
Check out the Eloquent ORM documentation here: https://laravel.com/docs/5.3/eloquent
First create the UserModel and KomenModel.
then use this
$queryData = UserModel::find($id);
foreach ($queryData as $data) {
$query2 = KomenModel::find($data->id);
}
or instead of above code you can do this using laravel join query.
There are two way of creating Queries...
1.Query...using normal DB::table...
2.Eloquent Model...
description
1.
`$data = DB::table('Tablname')->where('id',$id)->all();`
in here USE DB;
and there are severl methods such as all() , get()
2.
$this->model->where($attrib, '=', $value)->get();
where we go from the model option...
But as i understood you can go with DB query method..
$result= DB::table('komen')->where('id', $id)->all();
//check the previous query have got any data...
if($result)
{
//go for the second Query.....
}
If there is any need just mention...I am also new to laravel 5.3
You can get by following code without use any model.
$Data = DB::table('user')->where('id', '=', $id)->get();
foreach ($Data as $data) {
$query2 = DB::table('komen')->where('iduser', '=', $data->id)->get();
}
I've been struggling with this for a while. I've been reading about Eloquent and really trying hard to understand it, but nothing I try seems to work.
This is my MYSQL query that works perfectly:
SELECT jobs.id,
jobs.title,
application_statuses.description,
fee,
candidates.f_name,
candidates.l_name,
clients.name
FROM jobs
JOIN applications ON jobs.id = job_id
JOIN candidates ON candidate_id = candidates.id
JOIN application_statuses ON applications.status_id = application_statuses.id
JOIN clients ON client_id = clients.id
WHERE applications.status_id IN (3,4,5)
ORDER BY applications.status_id desc;
I've created models in Laravel but I can't get the results that I get with this raw query.
If possible could someone point me to somewhere where this sort of thing is explained (ie. multiple joins, and outputting data from all of the tables.), or help me with my predicament if it's not too much work?
I'm trying to do it without DB:RAW
Note. There's not much point me giving you my models and query as it's just a massive mess that I keep deleting and recreating.
Here is my code:
class PivotApplication extends Eloquent {
protected $guarded = ['id'];
protected $table = 'applications';
public function applicationStatus()
{
return $this->belongsTo("ApplicationStatus");
}
public function candidates()
{
return $this->belongsToMany("Candidate", "candidate_id");
}
}
class ApplicationStatus extends Eloquent {
protected $guarded = ['id'];
protected $table = 'application_statuses';
public function pivotApplication()
{
return $this->belongsToMany("PivotApplication");
}
}
class PipelineController extends \BaseController {
function __construct(Job $job, ApplicationStatus $application_status, PivotApplication $pivotApplication)
{
}
public function index()
{
//$appStatuses = ApplicationStatus::whereIn
$applications = PivotApplication::with("applicationStatus")->whereIn("status_id", [3,4,5])
//->applicationStatus()
->get();
//->toSql();
//dd(DB::getQueryLog());
return $applications;
die();
Sometimes an ORM like Eloquent will not achieve what you want from a raw SQL statement. Sometimes you need to approach the solution different from an ORM vs SQL.
Looking at your query - it would probably make sense to have 2-3 different ORM models doing different aspects of your query, and linking them via relationships.
However depending on the functionality - there is not necessarily a problem using a SQL statement for a specific use case in your program.
I dont quite understand where my code goes for this orm.
class Brand_model extends MY_Model {
public function add_brand($name, $size)
{
//goal:
// $sql = "insert into brand (name, size_id) values (?,?)";
// $query = $this->db->query($sql, array($name, $size));
$brand = new self();
$brand->name=$name;
$brand->size=$size;
$brand->save();
}
This produces a new row in the database, in the appropriate table, but with no data inside of it. However I am sure those variables are filled. Any ideas?
My design pattern pre orm is to put almost everything in the model. That way if multiple controllers need the same data structure, i call a function once and it handles all the validation/etc.
THanks!
Please find the link for eloquent and codeigniter integration
http://mannyisles.com/using-eloquent-orm-inside-codeigniter.html
To use the ORM, first of all, you would need the connection set up. You can look into this answer. It tells you how to set up eloquent DB connection.
Once it is done, you need to create a model, which would extends the ORM, and do all your DB calls using that model.
You can create a file - let's say, FooModel.php like this:
<?php
namespace Models\FooModel;
use Illuminate\Database\Eloquent\Model;
class FooModel extends Model
{
protected $table = 'sample_table';
protected $fillable = array('comma', 'seperated', 'column', 'names');
protected $hidden = array('id');
public $timestamps = true;
}
?>
$fillable tells eloquent which columns you want to write into. you can ignore the auto incremented columns and the columns with default values.
$timestamps handle your created_at and updated_at columns, if you have any.
When you have to create the row, you can call the eloquent create() function. This function requires an associative array with column names as key and values as the corresponding value you wanna insert to that column.
$row = array('name' => 'Foo',
'email' => 'foo#bar.com'
);
You can then just call the create function, with $row as a parameter.
$response = FooModel::create($row);
If you do a var_dump($response); you can see the status of the create(). true for success or the error message.
For further info you can check out the Docs. It's really not that hard!
Cheers! :)