hasMany and belongsTo Laravel - mysql

I have 3 models. User, Notification and Lmo Notifications. The relation is a User hasMany Notifications and Notification has many LmoNotification.
to insert the notification and lmoNotification i created two models and controllers and they have separate database tables.
My problem is when i enter notifications into the database, it inserts data without any problem with user_id as the foreign key. But next when i try to enter the lmonotification, it gives an error.
Notification Model:
class Notification extends Model
{
protected $table = "notifications";
protected $fillable = [
'unit_code', 'unit_name', 'project_title', 'project_ref_number', 'storage_location', 'keeper_name', 'user_id',
];
public function user(){
return $this->belongsTo('App\User');
}
}
LmoNotification Model
class AddLmoNotification extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table = "lmo_notifications";
protected $fillable = [
'lmo_name', 'lmo_risk_level', 'lmo_quantity', 'lmo_volume', 'notification_id',
];
public function notification(){
return $this->belongsTo('App\Notification');
}
}
Notification controller to create the notification
public function create(Request $request)
{
$notification = Notification::create([
'unit_code'=>$request->unit_code,
'unit_name'=>$request->unit_name,
'project_title'=>$request->project_title,
'project_ref_number'=>$request->project_ref_number,
'storage_location'=>$request->storage_location,
'keeper_name'=>$request->keeper_name,
'user_id'=>Auth::user()->id
]);
return redirect()-> route('show.lmo_form', $notification->id);
// return view('ApplicationForms.notifi', $notification);
}
Lmonotification controller
$notification = new Notification;
/*this loop is because im adding rows dynamically to the table*/
$count = count($request->input('lmo_name'));
for ($i=0; $i<$count; $i++){
$data = AddLmoNotification::create([
'lmo_name'=>$request->lmo_name[$i],
'lmo_risk_level'=>$request->lmo_risk_level[$i],
'lmo_quantity'=>$request->lmo_quantity[$i],
'lmo_volume'=>$request->lmo_volume[$i],
'notification_id'=>$notification->id
]);
return response($data);
}
//return response($notification);
return redirect()->route('show.go_to_notification');
}
web.php
Route::prefix('notification')->group(function(){
/*show notification main page*/
Route::get('/', 'HomeController#getNotificationPage')->name('show.go_to_notification');
/*route to lmo_notification_form*/
Route::get('/personal_information_notification_form', 'HomeController#getNotificationForm');
/*route to biohazardous material notification form*/
Route::get('/biohazardous_material_notification_form', 'HomeController#getotherNotificationForm')->name('show.biohazardous_material_notification_form');
/*submit lmo notification route*/
Route::post('/personal_information_notification_form/submit', 'NotificationController#create')->name('submit.personal_Info_Notification');
/*Rtoute to lmo form*/
Route::get('/personal_information_notification_form/add_lmo/{notification_id}', 'HomeController#getlmoNotificationForm')->name('show.lmo_form');
/*Route to submit lmo list for notification*/
Route::post('/personal_information_notification_form/add_lmo', 'LmoNotificationController#create')->name('submit.lmo_list');
});
Notification table
Schema::create('notifications', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->string('unit_code')->nullable();
$table->string('unit_name')->nullable();
$table->string('project_title')->nullable();
$table->string('project_ref_number')->nullable();
$table->string('storage_location');
$table->string('keeper_name');
$table->timestamps();
});
Lmo Notification table
public function up()
{
Schema::create('lmo_notifications', function (Blueprint $table) {
$table->increments('id');
$table->integer('notification_id')->unsigned();
$table->foreign('notification_id')->references('id')->on('notifications')->onDelete('cascade')->onUpdate('cascade');
$table->string('lmo_name');
$table->string('lmo_risk_level');
$table->string('lmo_quantity');
$table->string('lmo_volume');
$table->timestamps();
});
}
the notification table contains some personal details fields and the lmonotification contains list of products.
the error message says that
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'notification_id' cannot be null (SQL: insert into lmo_notifications (lmo_name, lmo_risk_level, lmo_quantity, lmo_volume, notification_id, updated_at, created_at) values (asd, medium, 2, 2, , 2017-05-09 22:35:15, 2017-05-09 22:35:15))
Please help.

There is nothing wrong with your relations setup. The problem starts where you set the notification_id of your new AddLmoNotification off of a model you instantiated with:
$notification = new Notification;
Note that as long as $notification is not persisted to database with:
$notification->save()
that notification will not have an ID assigned to it by the database, and thus, accessing its id attribute returns null. So you'll have to save the $notification model first, before creating any models that rely on its id attribute for their foreign-key fields.

Related

How to get auth()->user() in api controller Laravel

I want to get the logged in user id and insert it into the Salesprice table,I have tried the below code but it gives me the this error
"SQLSTATE[HY000]: General error: 1364 Field 'setby_id' doesn't have a
default value (SQL: insert into salesprices (book_id,
salesprice, remarks, updated_at, created_at) values (2, 5566,
?, 2020-01-31 03:59:58, 2020-01-31 03:59:58))"
code in controller is
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Salesprice;
use Illuminate\Support\Facades\Hash;
use App\User;
use Illuminate\Support\Facades\Auth;
public function store(Request $request)
{
try
{
$user = auth('api')->user();
$this->validate($request,[
'book_id'=>'required',
'salesprice'=>'required',
]);
$Salesprice= Salesprice::create([
'book_id'=>$request['book_id'],
'salesprice'=>$request['salesprice'],
// 'setdate'=>$request['setdate'],
'setby'=> $user->id,
'lastmodifiedby'=>$user->id,
'remarks'=>$request['remarks']
]);
return response()->json($Salesprice);
}
catch (Exception $e)
{
return response()->json($e->getMessage(), 500);
}
}
code in migration and model is
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Salesprice extends Model
{
//
use SoftDeletes;
protected $fillable = [
'book_id','salesprice','setby_id','modifiedby_id','remarks'
];
public function Book()
{
return $this->hasOne('App\Book');
}
public function User()
{
return $this->hasOne('App\User');
}
protected $dates=['deleted_at'];
}
public function up()
{
Schema::create('salesprices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('book_id')->unsigned();
$table->bigInteger('salesprice');
$table->bigInteger('setby_id')->unsigned();
$table->bigInteger('modifiedby_id')->unsigned();
$table->string('remarks')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
auth()->user()is correct
The only thing you have to do is to change your
setby to setby_id Becaseu you're doing:
'setby'=> $user->id,
but your column is named setby_id, so you need:
'setby_id'=> $user->id,
Because this field cannot be nullable.
So when you insert the value without setby_id, it will fail.
Change setby to setby_id
$Salesprice= Salesprice::create([
...
'setby_id'=> $user->id, // change to setby_id
...
]);
Nothing's wrong with auth()->user().
You're doing:
'setby'=> $user->id,
but your column is named setby_id, so you need:
'setby_id'=> $user->id,
You'll have the same issue with lastmodifiedby versus modifiedby_id.

on delete cascade laravel

Morning everyone,
I have foreign keys set to on delete cascade in laravel 5 and mysql on a couple of tables where the existence of a employee depends on the existence of the country he was born in.
$table->foreign('id_estado_municipio')
->references('id_estado_municipio')
->on('cat_municipios')
->onDelete('cascade')
->onUpdate('cascade');
Problem is when I delete the country, the employee that must get erased along with it, gets erased from the database, but the employee's record keeps on showing at the index view.
Have tried setting engine to InnoDB in the config file, model observers to delete dependents but still can't figure out how to make it work.
Hopefully someone can give some light. It would be very much appreciate it.
Here you are my models and modelcontrollers
class Municipio extends Model
{
//
protected $table = 'cat_municipios';
protected $primaryKey = 'id_estado_municipio';
...
public function trabajadores()
{
return $this->hasMany(Trabajador::class,'id_trabajador');
}
protected static function boot() {
parent::boot();
static::deleting(function($municipio) {
// delete related stuff ;)
$municipio -> trabajadores() -> delete();
});
}
class MunicipioController extends Controller
{
...
public function destroy($id)
{
//
$municipio = Municipio::findOrFail($id);
$municipio -> trabajadores() -> delete();
$destruido = Municipio::destroy($id);
if($destruido)
return redirect()->route('Municipio.index')->with('info','Municipio eliminado con éxito.');
else
return redirect()->route('Municipio.index')->with('error','Imposible borrar Municipio.');
}
}
////////////////////////////////////////
class Trabajador extends Model
{
//
protected $table = 'trabajadors';
protected $primaryKey = 'id_trabajador';
...
public function municipio()
{
return $this->belongsTo(Municipio::class,'id_estado_municipio');
}
...
}
class TrabajadorController extends Controller
{
public function index()
{
//
$criterio = \Request::get('search'); //<-- we use global request to get the param of URI
$estadosciviles = EstadoCivil::orderBy('id_estado_civil')->paginate(50);
$estados = Estado::orderBy('id_estado') -> paginate(50);
$municipios = Municipio::orderBy('id_estado_municipio')->paginate();
$religiones = Religion::orderBy('id_religion')->paginate();
$trabajadores = Trabajador::where('nombre', 'like', '%'.$criterio.'%')
->orwhere('id_trabajador',$criterio)
->orwhere('a_paterno',$criterio)
->orwhere('a_materno',$criterio)
->orwhere('curp',$criterio)
->orwhere('rfc',$criterio)
->orwhere('seguro_social',$criterio)
->sortable()
->orderBy('id_trabajador')
->orderBy('nombre')
->paginate();
return view('Trabajador.index', array('trabajadores' => $trabajadores,'estadosciviles' => $estadosciviles,'estados' => $estados,'municipios' => $municipios,'religiones' => $religiones));
}
...
}

create Notification in 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?

Yii2 How to create a globally accessible variable that converts user's id to employee's id

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;

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