I have the database like this
=== Invoice ===
id
customer_id (FK)
description
=== Customer ===
id
firstname
lastname
I have multimodel for both the form so that Cstomer table will be load in Invoice. So that I can easily access the two models from a single view. For that I have made relation in both models just like this
In Invoice model the realtion is like this
public function relations()
{
return array(
'customer' => array(self::BELONGS_TO,'Customer','customer_id'),
);
}
In Customer Model the relation is like this
public function relations()
{
return array(
'invoice' => array(self::HAS_MANY, 'Invoices','customer_id')
);
}
Everything is working fine.But when I am going for actionUpdate() in Invoice controller file there is Customer model is not defined. So I made it define like this
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id),
'customers'=>Customers::model()->findByPk(array('customer_id'=>$_GET['id']));
));
}
It is showing as Undefined offset: 0. I want here in ('customer_id'=>$_GET['id']) the value of id so that I can easily show and update the values for each ids.
If I am giving the value like this
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id),
'customers'=>Customers::model()->findByPk(28);
));
}
It is easily showing the value from Customer id. So how to get those values?Any help and suggestions will be highly appriciable.
Try this
public function actionView($id)
{
$model = $this->loadModel($id);
$this->render('view',array(
'model'=>$model,
'customers'=>Customers::model()->findByPk($model->customer_id);
));
}
Related
I have the below tables and I want to retrieve the number of each comment likes with users that liked the comment (something like Instagram comment which any body can like another user comments)
users table
id
name
Asks table
id
title
comments table
id
ask_id
user_id
text
comment_like table
id
comment_id
user_id
it used for saving comment links, it looks like Instagram comment which any user can like another user comment.
here is my User Model Code:
class User extends Authenticatable
{
public function comments_like()
{
return $this->belongsToMany(
Comment::class,
'comment_like' ,
'user_id' ,
'comment_id' ,
'id',
'id'
);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
here is my Ask Model Code:
class Ask extends Model
{
use HasFactory;
protected $table = 'asks';
protected $fillable = ['title'];
public function comments()
{
return $this->hasMany(Comment::class);
}
}
here is my User Model Code:
class User extends Authenticatable
{
public function comments_like()
{
return $this->belongsToMany(
Comment::class,
'comment_like' ,
'user_id' ,
'comment_id' ,
'id',
'id'
);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
here is my Comment Model Code:
class Comment extends Model
{
//user relation
public function user()
{
return $this->belongsTo(User::class);
}
//ask relation
public function ask()
{
return $this->belongsTo(Ask::class);
}
//comment_like relation
public function users_like ()
{
return $this->belongsToMany(
User::class ,
'comment_like',
'comment_id',
'user_id',
'id',
'id'
)
->withTimestamps();
}
//condition on comment_like relation
public function user_like_byId($id)
{
return $this->belongsToMany(
User::class ,
'comment_like',
'comment_id',
'user_id',
'id',
'id'
)
->where('id',$id)->get();
}
}
I want to retrieve latest ask with their comments which include count and data of comment_like**
I used this code but it show error
$ask= Ask::query()->latest('id')->get()->first();
foreach ($ask->comments()->get() as $commentItem) {
echo "id: ".$commentItem->id .'<br>';
echo "name :" .$commentItem->user()->pluck('name')[0] . "<br>";
echo "text :" .$commentItem->text . "<br>";
echo $commentItem->user_like_byId($commentItem->id);
}
You can create a resource with php artisan make:resource AskResource for your fetched data and use count() function for get length of data.
I have free tables: user, book, user_book, offers
user table has method:
public function getBooks()
{
return $this->hasMany(UserBook::className(), ['user_id' => 'id']);
}
user_book table has two fields: user_id, book_id; and methods
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
public function getBook()
{
return $this->hasOne(Book::className(), ['id' => 'book_id']);
}
table offer have method like: getUser(), getBook(),
and now I would like show Books which user don't have. I try do something like
$query = Offer::find()
->with('user')
->andWhere([
'offer.status' => Offer::STATUS_ACTIVE,
]);
$query->andWhere(['not in', 'offer.book_id', 'user.books.book_id']);
but it doesn't work. Do you have some ideas how can I make it?
Yii2 docs, relation via junction table
In database modelling, when the multiplicity between two related
tables is many-to-many, a junction table is usually introduced. For
example, the order table and the item table may be related via a
junction table named order_item. One order will then correspond to
multiple order items, while one product item will also correspond to
multiple order items.
When declaring such relations, you would call either via() or
viaTable() to specify the junction table. The difference between via()
and viaTable() is that the former specifies the junction table in
terms of an existing relation name while the latter directly uses the
junction table. For example,
class Order extends ActiveRecord
{
public function getItems()
{
return $this->hasMany(Item::className(), ['id' => 'item_id'])
->viaTable('order_item', ['order_id' => 'id']);
}
}
or alternatively,
class Order extends ActiveRecord
{
public function getOrderItems()
{
return $this->hasMany(OrderItem::className(), ['order_id' => 'id']);
}
public function getItems()
{
return $this->hasMany(Item::className(), ['id' => 'item_id'])
->via('orderItems');
}
}
I am new to yii. I have created two table, user and notification. The table notification has userid as a foreign key. I want to create notification against user in user model just like I get notification from user model
public function getnotifications()
{
return $this->hasMany(Notification::className(), ['user_id' => 'id']);
}
Use this function in your model.
public function addNotification() {
$notification = new Notification();
$notification->user_id = $this->id;
$notification->message = "Notification";
$notification->save();
}
Apart from the name of your function ( should be getNotifications() not getnotifications() ), I see nothing wrong in your code.
public function getNotifications()
{
return $this->hasMany(Notification::className(), ['user_id' => 'id']);
}
What is the problem now?
I have two tables that are related directly in a one-to-one relationship. One is the standard Yii2 user table (abbreviated field list here for clarity) and the other is the employee table that contains user_id. How can I create a globally accessible variable (and the actual code to access the employee id) that I can use anywhere in my application that will give me the logged in user's employee id and how would I call that variable? I wish I could say that I've tried a few things, but unfortunately I am relatively new to Yii2 and have no idea where to start with global variables like this. Thanks for any help.
user table:
id
username
password
etc
employee table:
id
user_id (related in a one-to-one relationship to the user table)
The Employee Model:
<?php
namespace frontend\models\base;
use Yii;
/**
* This is the base model class for table "employee".
*
* #property integer $id
* #property integer $user_id
*
* #property \common\models\User $user
*/
class Employee extends \yii\db\ActiveRecord
{
public function rules()
{
return [
[['user_id', 'required'],
[['user_id'], 'integer'],
[['user_id'], 'unique']
];
}
public static function tableName()
{
return 'employee';
}
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'user_id' => Yii::t('app', 'User ID'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(\common\models\User::className(), ['id' => 'user_id']);
}
}
A very simple way is the use of $param array
You can initially config the default value in
your_App\config\param.php
and accessing using
\Yii::$app->params['your_param_key']
Looking to your Employee model (for me ) you don't need a global var you could simply use the getUser
$myUser = Employee::user();
but you need the param you can assign using
\Yii::$app->params['my_user'] = Employee::user();
or in user
\Yii::$app->params['my_user'] = Yii::$app->user->id
or for retrive the model related to actual user from table
$myEmpModel = Employee::find()->where['user_id' => Yii::$app->user->id]->one();
I believe proper way is to use relations in your User model. First method is proper relation with activerecord, second one will get id using relation defined above it. so You will add these methods in your User model:
/**
* #return \yii\db\ActiveQuery
*/
public function getEmployee()
{
return $this->hasOne(Employee::className(), ['user_id' => 'id']);
}
public function getEmployeeId()
{
return $this->employee ? $this->employee->id : NULL; // set to NULL or anything you expect to be if record is not found
}
Then you can call it like this from everywhere in your app:
$employee_id = Yii::$app->user->identity->employeeid;
This will only work for User model because it implements Identity, otherwise you would need to instantiate model class first, lets say like this:
$user_id = 5; // 5 is id of user record in DB
$user = User::findOne($user_id);
$employee_id = $user->employeeid;
// or using first of 2 relations ...
$employee_id = $user->employee->id;
I have a Model called User and another Model called Roles and they are linked with each other through a belongsToMany relationship. But I needed to cast certain pivot attributes so I used a custom pivot class RoleUserPivot which basically looks like follows:
...
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleUserPivot extends Pivot
{
protected $casts = [
'active' => 'boolean',
'permissions' => 'array',
];
}
...
The relationship definition in User and Role models is as follows:
...
// User Model
public function roles()
{
return $this
->belongsToMany('App\Role')
->withPivot(
'active',
'permissions'
);
}
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
if ($parent instanceof Role) {
return new RoleUserPivot($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
...
And similarly:
...
// Role Model
public function users()
{
return $this
->belongsToMany('App\User')
->withPivot(
'active',
'permissions'
);
}
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
if ($parent instanceof User) {
return new RoleUserPivot($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
...
The problem I am having is, while the active field is properly cast to boolean, the permissions field is not cast to array, instead the same string in the database is returned. I assure that the pivot table is properly setup and permissions column is MySQL TEXT column.
Currently I am using Laravel 5.1.16 (LTS).