create Notification in yii2 - yii2

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?

Related

hasOne with null-able in laravel not working

I have a customer table which has a field called 'policy_id', where policy_id points to policy table. It is a null-able field, ie. Some customers may not have a policy.
I have a relationship code like this in Customer.php
public function policy() {
return $this->hasOne('App\Models\Policy', "id", "policy_id");
}
But when I issue a search request I am getting error like this:
Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\Policy]
If I modify the function like this:
public function policy() {
if ($this->getAttribute('policy_id')) {
return $this->hasOne('App\Models\Policy', "id", "policy_id");
} else {
return null
}
}
But I am getting an error like this:
Call to a member function getRelationExistenceQuery() on null
Here is my search code:
$c = new Customer();
return Customer::doesntHave('policy')->orWhere(function (Builder $query) use ($req) {
$query->orWhereHas('policy', function (Builder $query) use ($req) {
$p = new Policy();
$query->where($req->only($p->getFillable()))
->orWhereBetween("policy_period_from", [$req->policy_period_start_from, $req->policy_period_start_to])
->orWhereBetween("policy_period_to", [$req->policy_period_end_from, $req->policy_period_end_to])
->orWhereBetween("payment_date", [$req->payment_date_from, $req->payment_date_to]);
});
})->where($req->only($c->getFillable()))->get();
Am I missing something or are there any other ways to do this?
PS: While debugging the above search code is returning successfully, but the exception happening from somewhere inside Laravel after the prepareResponse call.
Thanks in advance.
return $this->hasOne('App\ModelName', 'foreign_key', 'local_key');
Change the order, put the foreign_key policy_id in front of id
In your Customer Model, you need to use belongsTo method:
public function policy() {
return $this->belongsTo('App\Models\Policy', "policy_id", "id");
}
And In your Policy Model, use hasOne:
public function customer() {
return $this->hasOne('App\Models\Customer', "policy_id", "id");
}
First of all, you placed the wrong params.
$this->belongsTo('App\Models\Policy', "FK", "PK");
public function policy() {
return $this->belongsTo('App\Models\Policy','policy_id', 'id');
}
And for null value of policy_id you can use withDefault();
public function policy() {
return $this->belongsTo('App\Models\Policy','policy_id', 'id')->withDefault([
'name' => 'test'
]);;
}
there's a number of problems there but can you perhaps specify the namespace and the class of both your models - Customer and Policy.
By default, the models you create with php artisan make:model will use the \App namespace e.g. \App\Customer and \App\Policy.
Just double check that.
Also, with regards to the relationship, if the Laravel conventions have been followed you could just:
In the Customer model
public function policy() {
return $this->belongsTo(Policy::class);
}
In the Policy model
public function customer() {
return $this->hasOne(Customer::class);
}
of if a multiple customers can be under one policy
public function customers() {
return $this->hasMany(Customer::class);
}
Good luck

Yii2 property mapping to tablename

I use Yii2 2.0.9 basic template and I try to set up my class.
I my class I use references of other classes in my property.
/**
*
*#property Contact contact
*/
class User extends ActiveRecord {
public static function tableName() {
return "user";
}
/**
* This is want I need
*/
public function databaseMapping(){
return [
"contact" => "contact_id"
];
}
}
Is there in Yii2 a solution for my problem?
Thanks Marvin Thör
In Grails I can write this:
class User {
Contact contact
Boolean passwordExpired
static mapping = {
contact(column: 'contact_id')
passwordExpired(column: 'password_expired')
}
}
User user = new User();
user.passwordExpired = true
user.contact = new Contact();
and I want the same
You might want to use the method attributeLabels() inside your model class to define label names to show to the end user.
public function attributeLabels() {
return [
'contact_id' => 'Contact',
];
}
However, there are times like when creating a RESTful API using Yii2 that you need to return a json with fields with specific field names. For these ocasions, you can use the fields() method:
public function fields() {
return [
'contact' => 'contact_id',
];
}
This method returns the list of fields that should be returned by default by toArray(). You can check more about it HERE.
Change your labels and db column remain unchanged.
public function attributeLabels()
{
return [
'contact_id' => Yii::t('app', 'Use your name here'),
];
}

How to use Relation::morphMap() for diffrent class

I am using laravel polymorphic relation.
I have defined two morphTo relations for two purpose.
My question is that ,but when I am defining the key of Relation::morphMap() function array , then my array key is same for one case, so I want to know is there any way by which I can specify that I am defining relation for specific class.
My first relation....
Package.php
public function provider()
{
return $this->morphTo(null, 'map_type_id', 'map_id');
}
Venue.php
public function packages()
{
return $this->morphMany(VendorPackage::class, 'map', 'map_type_id', 'map_id');
}
Vendor.php
public function packages()
{
return $this->morphMany(VendorPackage::class, null, 'map_type_id', 'map_id');
}
I want to set the key to compare with map_type_id so I am setting the key in service provider.
Relation::morphMap([
config('evibe.roles.planner') => \Vendor::class,
config('evibe.roles.artist') => \Vendor::class,
config('evibe.roles.venue') => \Venue::class,
], false);
My 2nd morphTo relation
Ticket Booking.php
public function provider()
{
return $this->morphTo(null, 'map_type_id', 'map_id');
}
Venue.php
public function bookings()
{
return $this->morphMany(TicketBooking::class,null,'map_type_id','map_id');
}
Decors.php
public function bookings()
{
return $this->morphMany(TicketBooking::class,null,'map_type_id','map_id ');
}
Now again I have to define the morphTo in service provider because I am not using the default Model name.
so my morphTo in service providers became like this.
Relation::morphMap([
config('evibe.roles.planner') => \Vendor::class,
config('evibe.roles.artist') => \Vendor::class,
config('evibe.roles.venue') => \Venue::class,
config('evibe.ticket_type.venues') => \Venue::class,
config('evibe.ticket_type.decors') => \Decor::class
], false);
Now my problem is that key config('evibe.roles.planner') and config('evibe.ticket_type.venues) has the same value 3, so when both things is accessed by the relationship then it is throwing error, because array have same key.
So I want to ask is there any other way to define different morphMap for different relationship.
Lets start by defining the polymorphic relations
First relation....
Package.php
public function provider() {
return $this->morphTo(null, 'map_type_id', 'map_id');
}
Venue.php
public function packages() {
// you should provide the relation name, in our exemple its called `provider` as a second parameter
return $this->morphMany(VendorPackage::class, 'provider', 'venues');
}
Vendor.php
public function packages() {
// you should provide the relation name, in our exemple its called `provider` as a second parameter
return $this->morphMany(VendorPackage::class, 'provider', 'vendors');
}
Second Relation
TicketBooking.php
public function provider() {
return $this->morphTo(null, 'map_type_id', 'map_id');
}
Venue.php
public function bookings() {
return $this->morphMany(TicketBooking::class, 'provider', 'venues');
}
Decors.php
public function bookings() {
return $this->morphMany(TicketBooking::class, 'provider', 'decors');
}
and register Relation::morphMap as
Relation::morphMap([
'vendors' => \Vendor::class,
'venues' => \Venue::class,
'decors' => \Decor::class
]);

Difference between afterSave and a Event in yii2?

I wanted to send an email to admin when a new user registers. I think i can do it using two ways. one way is to use events and other is by using afterSave.
By using Events
Controller code
public function actionCreate()
{
$model = new Registeration();
if ($model->load(Yii::$app->request->post()))
{
if($model->save())
{
$model->trigger(Registeration::EVENT_NEW_USER);
}
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
Model code
const EVENT_NEW_USER = 'new-user';
public function init(){
$this->on(self::EVENT_NEW_USER, [$this, 'sendMail']);
}
public function sendMail($event){
// code
}
I can do the same using the afterSave method
Model code
public function afterSave($insert)
{
//code
return parent::afterSave($insert);
}
So is there any difference between the two methods? Which one is better using Events or afterSave() ?
I am new to Yii,
It depends on what you are trying to implement.
When you use afterSave email will be sent on updates also.
So event would be a better choice to your problem.
Thanks & Regards
Paul P Elias

action Update() in Yii to update another model's update

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