Update Foreign Key with softDeletes() - laravel-5

Hi I've been looking for the similar solution but can't find anywhere. I don't even know if there is one. What I am trying to do is perform a softDelete on one of my model and want to update the user_id in the model with the the id of the user performing the action. I have tried using associate(), it doesn't throw any exception but does not work. I mean the delete is working but id is not updating
Here's what I've tried
public function postDelete(Request $request){
$appointment = \App\Models\emp_appointment::findOrFail($request->appid);
$user = $request->user();
$appointment->user()->associate($user);
$appointment->delete();
}
Here's my Appointment Model
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class emp_appointment extends Model{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function employee(){
return $this->belongsTo('App\Models\employee','emp_id');
}
public function user(){
return $this->belongsTo('App\Models\tb_login','userid');
}
}
PS: There are no problems in the models and no errors anywhere. Only the problem is userid doesn't get updated in the appointment table.

Seems like the delete method isn't saving your change (association)
Try saving first then deleting
public function postDelete(Request $request){
$appointment = \App\Models\emp_appointment::findOrFail($request->appid);
$user = $request->user();
$appointment->user()->associate($user);
$appointment->save();
$appointment->delete();
}
EDIT
public function postDelete(Request $request){
$appointment = \App\Models\emp_appointment::findOrFail($request->appid);
$user = $request->user();
$appointment->user()->associate($user);
$appointment->deleted_at= date('Y-m-d H:i:s');
$appointment->save();
}

Related

Eloquent relationship update appropriate database fields in Laravel

I have BelongsTo model between 3 database (Admins, vendors, and vendor_business_table) table in Laravel. Trying to save the data which comes from HTML form in appropriate database field. My Admin Model looks like below:
class Admin extends Authenticatable
{
use HasFactory;
protected $guard = 'admin';
public function getVendorDetails(){
return $this->belongsTo(Vendor::class, 'vendor_id','vendor_id');
}
public function getVendorBusinessDetails(){
return $this->belongsTo(VendorBusinessDetails::class, 'vendor_id','vendor_id');
}
}
Once all the data is sent from the form I am trying to catch and save the fields. We have only id field is foreign key.
public function editVendorsDetails(Request $request,$id){
if($request->isMethod('post')){
$data = $request->all();
$myModel = Admin::with('getVendorDetails')->find($id);
$myModel->getVendorDetails->fill($data);
$myModel->getVendorDetails->save();
Once I save the form nothing is changed. Am I missing something here? Your help would be highly appreciated.
Would you please replace your code with this code in editVendorDetails()
if($request->isMethod('post')){
$data = $request->all();
$myModel = Admin::with('getVendorDetails')->find($id);
$myModel->getVendorDetails()->create($data);
}
// fill this array which field you want to store like name
protected $fillable = ['name'];
or
protected $guarded = [];
Have a look at is Mass Assignment Documantation.

laravel 8 store request with foreign key user_id not working

I would like to store the corresponding logged in user when adding a new School data. What I'm trying to do is store the logged in user_id in the schools table, in order to know on who added the school data. I have a users table already, which will establish the relation in the schools table.
My goal is when an admin is logged in, he/she can see all of the School records, otherwise if it's a user, then only fetch the records he/she added. The problem is that I can't figure out on when and where to insert the user_id data during the store request as I'm getting an error "user id field is required". Here's what I've tried so far:
Migration:
class CreateSchoolsTable extends Migration
{
public function up()
{
Schema::create('schools', function (Blueprint $table) {
$table->id();
$table->string('school_name');
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->timestamps();
});
}
}
School Model:
class School extends Model
{
use HasFactory;
protected $fillable = ['school_name', 'user_id'];
public function User() {
return $this->belongsTo(User::class);
}
}
Store Request:
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255',
'user_id' => 'required|exists:users,id'
];
}
}
Controller:
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
$school_data = $request->validated();
$user_id = \Auth::user()->id;
$school_data['user_id'] = $user_id;
School::create($school_data );
return Redirect::route('schools.index');
}
}
Any inputs will be of big help! Thanks.
Laravel has elegant way to bind authenticated user_id. Remove user_id from request class and chaining method. Also setup relationship from User model to School Model
Form Request Class
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255',
];
}
}
User Model
protected $fillable = ['school_name', 'user_id'];
...
// new line
public function schools() {
return $this->hasMany(School::class);
}
Your Controller
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
auth()->user()->schools()->create($request->validated());
return Redirect::route('schools.index');
}
}
UPDATE ANSWER
Since user_id value is school name (based on image link from comment), probably there's something wrong either in User or School model. Here the quick fix
Your Controller
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
auth()->user()->schools()->create(
array_merge(
$request->validated(),
['user_id' => auth()->id()]
)
);
return Redirect::route('schools.index');
}
}
You can add 'created_by' and 'updated_by' fields to your table. so you can register in these fields when additions or updates are made.
Then you can see who has added or updated from these fields.
class School extends Model
{
use HasFactory;
protected $fillable = ['school_name', 'user_id', 'created_by', 'updated_by'];
public function User() {
return $this->belongsTo(User::class);
}
}
Your controller part is correct but since you get the logged in user, you wont be having user_id in the request. So you should remove the rules about user_id from your StoreSchoolRequest.
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255'
];
}
}
Problem is here ..
$school_data = $request->validated();
Since you are using $request->validated()..
You have to safe()->merge user_id into it , here Docs : .
$validated = $request->safe()->merge(['user_id' => Auth::user()->id]);
Then put this $validated into create query , Thanks. –

How do i delete all rows based on a single column in one to many relationship in laravel eloquent?

When deleting a particular movie , i want to delete all showtime related to it. I have 3 tables related to this query.
Showtime (which has m-m relation with times table (pivot table showtime_time)
Times
Movies
What i tried is:
MovieController:
public function destroy($id)
{
$movie = Movie::findOrFail($id);
if (ShowTime::where('movie_id', '=', $id)->exists()) {
$showtimes = ShowTime::whereIn('movie_id', '=', $id)->get();
foreach ($showtimes as $showtime) {
$showtime->times()->detach();
$showtime->delete();
$movie->delete();
}
return back();
} else {
$movie->delete();
}
return redirect()->route('movies.index');
}
Which gave me this error.
Argument 1 passed to
Illuminate\Database\Query\Builder::cleanBindings() must be of the type
array, string given, called in
C:\Users\lenovo\cinetime_nepal_backend\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php
on line 907
Model class
<?php
namespace Modules\Movie\Entities;
use Illuminate\Database\Eloquent\Model;
class Movie extends Model
{
protected $guarded = ['id']; //fillable
protected $hidden = ['created_at', 'updated_at'];
public function showTimes()
{
return $this->hasMany(ShowTime::class, 'movie_id');
}
}
This is how i am deleting showtime in showtimecontroller
ShowtimeController
public function destroy($id)
{
$showtime = ShowTime::findOrFail($id);
$showtime->times()->detach();
$showtime->delete();
return back();
}
I am new to laravel, i searched and tried many codes answered in this site but could not help myself.
Help Please
If you're using MySQL you can add 'ON DELETE CASCADE' to your foreign key. This will automatically delete any records that reference the parent when the parent is deleted. just put it to your showtime migration
$table->foreign('movie_id')->references('id')->on('movies')->onDelete('cascade');
Or, if you don't want that approach, then you can overwrite your delete method in your movie model. Put this code in your movie model.
public function delete() {
$this->showTimes()->times()->delete();
$this->showTimes()->delete();
parent::delete();
}
Then in your controller you just delete your movie and it's all fine.
public function destroy($id)
{
$movie = Movie::findOrFail($id);
$movie->delete();
return redirect()->route('movies.index');
}

Getting specific value when using eloquent from Laravel

I am using Laravel 5.2 and I need to get specific values from the database with a leftjoin. The code I am using is as follow:
public function commentList(Request $request)
{
$inputs = $request->all();
$commentList = Comment::select(
'projects_comments.id as comment_id',
'u.name as user_name',
'projects_comments.comment as comment',
'projects_comments.created_at as created_at'
);
$commentList->leftjoin('users AS u', 'projects_comments.user_id', '=', 'u.id');
if (!empty($inputs['project_ids'])) {
$commentList->where(function ($query) use ($inputs) {
foreach ($inputs['project_ids'] as $i) {
$query->orWhere('projects_comments.project_id', $i);
}
});
};
$data = $commentList->get();
return $data;
}
It works fine but I would like to know if there is a better way to do this using eloquent but I can't really understand how to write this for eloquent to work. I need to get all the comments from an array of project ids.
I have the following model for Comment:
class Comment extends Model
{
protected $table = 'projects_comments';
public $timestamps = true;
protected $guarded = ['id'];
public function project()
{
return $this->belongsTo('App\Project', 'project_id');
}
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
}
I assume what you want is to get Comments (with their users) that belongs to specific Projects provided by the user as an array of IDS
Comment::whereIn('project_id', $inputs['project_ids'])->with('user')->get();
And if you only want the id and name of the user associated with the comment, pass the fields to the with function like so
Comment::whereIn('project_id', $inputs['project_ids'])
->with('user:id,name')->get();

Trouble getting attribute of relation in Laravel

I'm having a trouble with a relation in Laravel 5. the thing is that I have a table User and that user belongs to a Group for that, in the User model I have this:
public function group(){
return $this->belongsTo('App\models\Group');
}
The model Group have this attributes: name,unity,level, init_date. I also put there a default function to return a group as String, this is the code:
public function __toString(){
return $this->name.' Unity '.$this->unity;
}
So, the thing that in a view a have many users and for each of them I want to display the unity, name,date. When I call $user->group it returns me correctly the name and the unity in a String (because the _toString function) that means that he is really querying the group perfectly, but then, when I want to access a simple attribute as unity,date,or name with $user->group->name Laravel gives me this error:
Trying to get property of non-object
I even tried $user->group()->name then I gets: Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name
Edited:
The model User:
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
protected $table = 'users';
protected $fillable = ['email', 'password','estate','filial_id','perfil_id','rol','cat_teacher'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
public function __toString(){
return $this->email;
}
public function filial(){
return $this->belongsTo('App\models\Filial');
}
public function perfil(){
return $this->belongsTo('App\models\Perfil','perfil_id');
}
public function grupo(){
return $this->belongsTo('App\models\Group','group_id','id');
}
}
The model Group:
class Group extends Model {
protected $table = 'groups';
protected $fillable = ['name','unity','date'];
public function filiales() {
return $this->belongsTo('App\models\Filial');
}
public function teacher(){
return $this->belongsTo('App\models\User','teacher_id');
}
public function users() {
return $this->hasMany('App\models\User');
}
}
Then, in the controller I made a dd($users) and there not appear the relations, appears other relations but not this one. In the view I want to print some of the attributes in a table, for that I have:
<td>{{$user->group}}</td>
<td>{{$user->group->unity}}</td>
The first line works perfectly, and I don´t know why.
The reason you're unable to return your group's name is that ->group() returns an instance of the query builder, and not an eloquent collection/object. Since a user belongs to a single group, modify your code in one of these two ways:
public function group(){
return $this->belongsTo('App\models\Group')->first();
}
And then access the group using one of the following methods:
$user = User::with("group")->where("id", "=", 1)->first();
$group = $user->group;
echo $group->name;
// OR
$user = User::where("id", "=", 1)->first();
$group = $user->group();
echo $group->name;
Or, leave the group() function as it is and access ->group()->first() on your $user object:
$user = User::where("id", "=", 1)->first();
$group = $user->group()->first();
echo $group->name;
Any of the above methods should properly return your group object's name (or other attributes). Check the Eloquent Documentation for detailed explanations on how to access these objects.

Resources