column aliasing in find() select in yii2 - php

I have 2 user_id in 2 tables and i want both idies in this query result
So how can i do it?
$ids = JobUser::find()->select('job_user.user_id AS agentId,job.user_id AS userId')
->join('LEFT JOIN', 'job', 'job.id = job_user.job_id')
->where('job_user.status="done" AND (job_user.proposed_date_time BETWEEN "'.date('Y-m-d H:i:s').'" AND "'. date('Y-m-d H:i:s', (time() + 90000)).'")')
->all();
how can we do colunm aliasing in yii2 through active record?

Add a public field in model with the same exact name used in alias
class yourModel extends \yii\db\ActiveRecord
{
public $agentId; // alias
and the proper value in attributes
and refer to this field with the alias name eg: in gridView
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'tipo',
['attribute' => 'agentId',
'label' => 'Agent ID',

Related

Polymorphic relationships

I've got a master table called Product with the following columns:
id
product_id
product_type
name
price
in_stock
upc
Where ’id' and 'product_id' are unique (id is the PK)
I'll have other tables for different kinds of products (types).
All these other tables will have Product’s properties plus
Other properties on their own depending on the type of product
(I.e. clothing, records, etc.).
So I created a Product model using Polymorphic relationships
as follows:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'product_id',
'product_type',
'name',
'price',
'in_stock',
'upc'
];
public function categorizable()
{
return $this->morphTo();
}
}
And, for instance, a records model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Record extends Model
{
protected $fillable = [
    'artist_id',
    'title',
    'label',
    'code',
    'format',
    'number_of_discs',
    'image',
    'description'
];
public function products()
{
return $this->morphMany('\App\Product', 'categorizable');
}
public function artist()
{
return $this->belongsTo(Artist::class);
}
public function track()
{
return $this->hasMany(Track::class);
}
public function getItemDetails(int $itemId): array {
}
}
Whereas the columns for record are:
id
artist_id
product_id
title
label
This is the best way I could think of relating these tables.
My questions are:
Is there a better approach to this specific problem?
In this case (using polymorphic relationships), how would I insert a product?
How could I query a product in order to return data from
Both product table and record table? I mean, not a raw query
Since that I can do, but how to perform this query using
Eloquent?
Your code is perfect except product_id column in Record. You don't need that column, just remove it
how would I insert a product?
$product = Product::create([
'name' => $request->name,
'price' => $request->price,
'in_stock' => $request->in_stock
]);
$record->products()->save($product);
OR
$record->products()->create([
'name' => $request->name,
'price' => $request->price,
'in_stock' => $request-> in_stock,
'product_id' => $record->id,
'product_type' => get_class($record)
]);
If you need to create both then do it like this
$record = Record::create([
'artist_id' => $request->artist_id
'title' => $request->title,
'label' => $request->label,
'code' => $request->code,
]);
$product = Product::create([
'name' => $request->name,
'price' => $request->price,
'in_stock' => $request->in_stock
]);
$record->products()->save($product);
Fetch Data
$product = Product::with('categorizable')->find(2);
$product->categorizable; //this will be either Record, Cloth... instance
Similarly for record
$record = Record::with('products')->find(1);
$record->products; //it will give you product collection
For details you can look https://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations

Yii2 ArrayHelper::map left join select

I have users, orders and plans. When client buy plan, data is save in orders , plans are in account_plan and the information for user is in table users. In table orders is when the plan start and when it is expired. I use for Select2 ArrayHelper, but do not show the column
here is a query
$masAcc[0] = Yii::t('app', 'Choose plan');
$masAcc['----------------'] =
ArrayHelper::map(
\backend\models\Orders::find()
->select('orders.*,account_planLang.name as name')
->leftJoin('orders_props','`orders_props`.`order_id`= `orders`.`id`')
->leftJoin('account_plan','`orders_props`.`product_id`=`account_plan`.`id`')
->leftJoin('account_planLang','account_plan.id=account_planLang.plan_id')
->where('`orders`.`dt_end`<CURDATE() + INTERVAL 5 DAY AND `orders`.`dt_end`<CURDATE()')
->all(), 'id', 'name');
but the error is :
Getting unknown property: backend\models\Orders::name
here is Select2:
$form->field($model, 'account')->widget(Select2::classname(), [
'model' => $model,
'theme' => 'bootstrap',
'options' => [
'placeholder' => Yii::t('app', 'app.choose'),
'class' => 'form-control select2'
],
'data' => $masAcc,
'pluginOptions' => [
'allowClear' => true,
],
]);
}
That is because your query returns list of Orders models, which does not have name column, so it cannot represent result of this query. You need to use asArray() when you want to query field that is not available in model:
ArrayHelper::map(
\backend\models\Orders::find()
->select('orders.*,account_planLang.name as name')
->leftJoin('orders_props','`orders_props`.`order_id`= `orders`.`id`')
->leftJoin('account_plan','`orders_props`.`product_id`=`account_plan`.`id`')
->leftJoin('account_planLang','account_plan.id=account_planLang.plan_id')
->where('`orders`.`dt_end`<CURDATE() + INTERVAL 5 DAY AND `orders`.`dt_end`<CURDATE()')
->asArray() // <- this
->all(),
'id',
'name'
);
Or add name field to your model:
class Orders extends ActiveRecord {
public $name;
// ...
}
I guess there is no need to use ArrayHepler::map(). Try this way:
Orders::find()
->select('account_planLang.name as name, table_name.id as id')
->leftJoin('orders_props','`orders_props`.`order_id`= `orders`.`id`')
->leftJoin('account_plan','`orders_props`.`product_id`=`account_plan`.`id`')
->leftJoin('account_planLang','account_plan.id=account_planLang.plan_id')
->where('`orders`.`dt_end`<CURDATE() + INTERVAL 5 DAY AND `orders`.`dt_end`<CURDATE()')
->indexBy('id')
->column();

merge on column based relational table in gridview yii2

in index.php :
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'ID_REQUEST',
'NOMOR_SURAT',
[
'label' => 'Nama Depan',
'attribute' => 'ID_KARYAWAN',
'value' => 'iDKARYAWAN.FIRST_NAME'
],
[
'label' => 'Nama Belakang',
'attribute' => 'ID_KARYAWAN',
'value' => 'iDKARYAWAN.LAST_NAME'
],
which is iDKARYAWAN is relation from another table in my model
class Request extends \yii\db\ActiveRecord {
/**
* #inheritdoc
*/
public static function tableName() {
return 'ytms_it.request';
}
public function getIDKARYAWAN() {
return $this->hasOne(Karyawan::className(), ['ID_KARYAWAN' => 'ID_KARYAWAN'])->from(Karyawan::tableName(). ' b');
}
How to merge those two column ?
For the elp, thanks.
Create method called getFullName() in related model and calculate full name using PHP concatenation:
use yii\helpers\Html;
...
/**
* #return string
*/
public function getFullName()
{
return Html::encode($this->name . ' ' . $this->surname);
}
Optionally define a label for it in attributeLabels() method of related model:
`fullName` => 'Label for full name',
Then in GridView it's possible to display full name of related model in one column like so:
1) The shortest form:
'relatedModel.fullName',
2) Overriding the label:
[
'attribute' => 'relatedModel.fullName',
'label' => 'Overrided label',
],
3) Using closure:
[
'attribute' => 'relatedModel.fullName', // The attribute name can be different in this case
'value' => function ($model) {
// You can calculate full name here.
// But it's better to just call according method since view is only for display.
return $model->author->fullName;
},
],
Another way is to calculate full name using SQL and include as a part of query result in separate column.
Use Active Record - Selecting extra fields official docs section as a guide, also see this related issue on Github - JoinWith - assign a column aliases to an attribute of related model.
Add $fullName as public property of related model class. Modify query like so:
use yii\db\Expression;
...
->joinWith(['relatedModel' => function (\yii\db\ActiveQuery $query) {
$query->addSelect('fullName' => new Expression("CONCAT(name, ' ', surname)")]);
}]
Then to display it in GridView column you can use one of the options desribed above, for example:
'relatedModel.fullName'

Yii2. How to get access to the subquery field in a search model?

I have a search model:
$query = User::find();
$myOrdersQuery = Request::find()
->select('count(*)')
->where([
'user_id' => $clientsIds,
'agent_id' => $this->viewer->id,
]);
$query->addSelect(['my_orders_count' => $myOrdersQuery]);
When I'm trying to print it into the GridView
[
'attribute' => 'my_orders_count',
'value' => function ($model) {
return $model->my_orders_count;
}
],
it says Getting unknown property: common\models\User::my_orders_count
Please help to get access to this field
You can do like for calculated field
ad a public var in User model
public user_count;
use alias in select
.....
$myOrdersQuery = Request::find()
->select('count(*) as user_count')
->where([
....
then simply refer to the public field name in gridview
[
'attribute' => 'user_count',
],

Symfony form builder display two fields from db in the form property

In my table I have users and their full name is split into two fields: first_name and last_name. When displaying these users in a form it is only showing the persons first_name. How can I have both the first_name and the last_name in the select option, is this possible? Here is my current code, not sure where to go from here. Thanks.
$builder->add('buyer','entity',array(
'required' => false,
'class' => 'WICUserBundle:User',
'label' => 'User',
'property' => 'first_name', // <== how do I add the last_name here as well
'query_builder' => function(EntityRepository $er){
return $er->createQueryBuilder('u')
->where('u.account=?0')
->setParameters(array(
$this->account
));
},
'empty_value' => 'Select User',
));
Found the Answer Here: Symfony 2 Create a entity form field with 2 properties
define __toString() in entity class, remove property option from FormType class:
public function __toString()
{
return $this->firstField . ' - ' . $this->secondField;
}

Categories