how to run a query in looping in laravel? - php

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();
}

Related

Convert sql script to eloquent

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

How do I return my OUTPUT clause in Laravel DB::insert

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

How to delete multiple records using Laravel Eloquent

Now this, from what I can see, should have been simple.
I want to be able to delete multiple records from the database. I have the id's of all the records I wish to delete. I call the resource.destroy route using comma separated list of ids (id is of postgres type uuid), like so:
Request URL:http://foo.app/products/62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5
Request Method:DELETE
On the other end, my controller action looks like so:
public function destroy($id)
{
try {
$ids = explode(",", $id);
$org->products()->find($ids)->delete();
}
catch(...) {
}
}
This gives me the following error:
BadMethodCallException in Macroable.php line 81:
Method delete does not exist.
in Macroable.php line 81
at Collection->__call('delete', array()) in ProductsController.php line 251
at Collection->delete() in ProductsController.php line 251
at ProductsController->destroy('62100dd6-7ecf-4870-aa79-4b132e60c904,c4b369f1-d1ef-4aa2-b4df-b9bc300a4ff5')
I have verified that find() is returning a collection of products matching the specified ids.
What am I missing?
PS:
1. The model Product has several belongsTo relationships with other models.
2. The product.destroy code works fine if I pass it a single id
EDIT
I guess, I'm also trying to understand what the difference between:
$org->products()->find($ids)->delete()
and
$org->products()->whereIn('id', $ids)->get()->delete()
is? From what I see, both find and get are returning Collections
The issue is that you're calling delete() on a Collection, which does not have that method.
You have a couple options here.
Model Events
If you have event listeners for the deleting/deleted model events, you will need to make sure the deletion happens in a way that each model is loaded and then deleted.
In this case, you can use the destroy method on the model that takes a list of ids. It will load a new model for each id, and then call delete() on it. As you mention in a comment, it won't restrict the deletion to only those products in the organization, so you would need to filter out those ids before passing the list into the destroy() method.
public function destroy($id)
{
try {
$ids = explode(",", $id);
// intersect the product ids for the org with those passed in
$orgIds = array_intersect($org->products()->lists('id'), $ids);
// now this will only destroy ids associated with the org
\App\Product::destroy($orgIds);
}
catch(...) {
}
}
If you don't particularly like that approach, you will need to iterate your collection of organization products and call delete() on them individually. You can use a standard foreach, or you can use the each method on the collection:
public function destroy($id)
{
try {
$ids = explode(",", $id);
$org->products()->find($ids)->each(function ($product, $key) {
$product->delete();
});
}
catch(...) {
}
}
No Model Events
Now, if you don't have any model events that you need to listen for, things are a little easier. In this case, you can just call delete() on the query builder, and it will go straight to deleting the records without loading any model objects. So, you get cleaner code with better performance:
public function destroy($id)
{
try {
$ids = explode(",", $id);
// call delete on the query builder (no get())
$org->products()->whereIn('id', $ids)->delete();
}
catch(...) {
}
}
If you create a model of your products, it will help you with these types of operations.
For example:
the model Products.php
<?php
namespace App\Http\Models;
use Illuminate\Database\Eloquent\Model;
class Products extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'products';
protected $primaryKey = 'id';
protected $fillable = ['name', 'price', 'description'];
}
The controller Products.php
You can use the destroy method and pass one or more primary keys to it as arguments.
<?php
namespace App\Http\Controllers;
use App\Http\Models\Products;
class Products
{
public function destroy($id)
{
try {
$ids = explode(",", $id);
//$ids is a Array with the primary keys
Products::destroy($ids);
}
catch(...) {
}
}
}
You can also use this option to remove query results with a custom parameter
$deletedRows = Products::where('name', 'phones')->delete();
You can check the Laravel documentation https://laravel.com/docs/8.x/eloquent#soft-deleting
When you use the find method, it will find only a single ID. You should use a whereIn to match multiple ids
public function destroy($id)
{
try {
$ids = explode(",", $id);
$org->products()->whereIn('id', $ids)->get()->delete();
}
catch(...) {
}
}
This way you will find all the products with the given IDs and delete them all.
I also faced this problem. Let $orgs contains some records as a collection. Now you can easily delete these records using a loop like this-
foreach($orgs as $org)
{
$org->delete();
}

In Laravel 5.1, using Eloquent ORM, how does one update a single attribute for every relation?

I've been searching the documents everywhere and I can't figure this one out. Suppose I have set up a model with a hasMany relationship and the inverse like this:
class MasterAccount extends Model {
//master_account_id exists as a foreign key in sub_account table
//and references primary key in master_account table as
//defined in the migrations I set up for this
public function SubAccounts()
{
return $this->hasMany('App\SubAccount');
}
}
And I've made sure that some sub accounts have values matching the master account's primary id in the master_account_id column.
I've tested the relationship by dd()ing values in my controller like this:
public function edit(MasterAccount $masterAcct)
{
dd($masterAccount->subAccounts);
}
And this does successfully return a collection of all the related models. However, I cannot figure out how I would update a single attribute for every model that belongsTo MasterAccount -- shouldn't there be a way to cascade like this? I hacked it to work by doing this:
<?php namespace App\Http\Controllers;
use App\SubAccount;
public function update(MasterAccountRequest $request, MasterAccount $masterAccount)
{
//current request id
$id = $masterAccount->id;
//cascade global value to related Accounts
if ($request->some_value == 1)
{
//look more into this... ARGH!!!
SubAccount::where('master_account_id', '=', $id)->update(['this_value' => 1]);
}
}
And this works but I just KNOW there is some "Eloquent," way to do this.....right?
According to the documentation this should work:
<?php namespace App\Http\Controllers;
use App\SubAccount;
public function update(MasterAccountRequest $request, MasterAccount $masterAccount)
{
//current request id
$id = $masterAccount->id;
//cascade global value to related Accounts
if ($request->some_value == 1)
{
//look more into this... Wooooot!!!
$masterAccount->SubAccounts()->update(['this_value' => 1]);
}
}

How to efficiently select only the IDs of a Belongs To Many relationship in Eloquent?

If I have a Users table and Tags table, and a pivot table for a Belongs To Many relationship, how do I use Eloquent to load only the IDs of the relation?
If I do User::with('tags'), this will do a join on the pivot table and also a join on the tags table. However, this is unnecessary and inefficient in my case, as I want to be able to only select the IDs of the tags from the pivot table, not the other columns in the Tags table. In other words, I only want it to do a single join from Users to Users_Tags.
Thank you.
OK, since #WereWolf's suggestions are not correct (1st will cause error, 3rd might be wrong if there are custom keys), here are the options for you, that not fetch related models.
Starting with the most obvious:
// for single model:
$user = User::first();
$user->tags()->allRelatedIds(); // select id from related table -> join
This is what you may use, but it is not the answer, since you want to eager load those ids.
That being said, you need to create another model for pivot table:
// UserTag model
protected $table = 'user_tag';
// this is not required, just to make it read-only
public static function boot()
{
parent::boot();
static::saving(function() {
return false;
}
}
// User model
public function tagsPivot()
{
return $this->hasMany('UserTag')->select('tag_id', 'user_id'); // appropriate keys here
}
public function getTagsIds()
{
return $this->tagsPivot->lists('tag_id');
}
// then you can do this:
$users = User::with('tagsPivot')->get(); // no join, select category_id from pivot table
foreach ($users as $user)
{
$user->getTagsIds();
}
.
You can also make some changes on the User model, depending on your liking:
// to be able to do this:
$users = User::with('tagsIds')->get();
foreach ($users as $user)
{
$user->tagsIds;
}
// User model
public function tagsIds()
{
return $this->hasMany('UserTag')->select('tag_id', 'user_id'); // appropriate keys here
}
public function getTagsIdsAttribute()
{
if ( ! array_key_exists('tagsIds', $this->relations)) $this->load('tagsIds');
return $this->getRelation('tagsIds')->lists('tag_id');
}
Give it a try (not tested):
$user = User::query();
$ids = $user->getRelation('tags')->getRelatedIds();
Or maybe something like this (but does some extra queries during the tags call):
$user = User::find(1);
$ids = $user->tags->fetch('id');
Update: (Another way)
$user = User::find(1);
$ids = array_fetch(DB::table($user->joiningTable('tag'))
->where($user->getForeignKey(), $user->getKey())
->get(), 'tag_id');

Categories