How to delete posts of user at delete account? - php

I just made a delete function of accounts, but I'm stuck on a problem.I need to also delete posts of user, at delete account.How can I make that? I have table Users, where I have all details from users, and table Posts, where also have user_id and id,caption and image of post.
public function delete($id)
public function delete($id)
{
$profile = User::find($id);
$profile->delete();
Session::flash('remove', "The profile was successfully deleted!");
return redirect('login');
}
Profile.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
protected $guarded = [];
public function profileImage(){
$imagePath = ($this->image) ? $this->image : 'profile/vx2k9TEhkcgaRdOWKvs4lsxqOVmuzwumtwySEnvH.png';
return '' . $imagePath;
}
public function user(){
return $this->belongsTo(User::class);
}
public function followers(){
return $this->belongsToMany(User::class);
}
}
User.php
<?php
namespace App;
use App\Mail\NewUserWelcomeMail;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Mail;
use Actuallymab\LaravelComment\CanComment;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'username', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
protected static function boot()
{
parent::boot();
static::created(function ($user) {
$user->profile()->create([
'title' => $user->username,
]);
});
}
public function posts()
{
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}
public function profile()
{
return $this->hasOne(Profile::class);
}
}
Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
public function user(){
return $this->belongsTo(User::class);
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
public function tags()
{
return $this->belongsToMany('App\Tag');
}
}
Migration posts table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}

I think you could try to delete related model in the controller before the user, i.e.:
public function delete($id)
{
$profile = User::find($id);
$profile->posts()->delete();
$profile->delete();
Session::flash('remove', "The profile was successfully deleted!");
return redirect('login');
}
Or you can go with model event, i.e.:
protected static function boot() {
parent::boot();
static::created(function ($user) {
$user->profile()->create([
'title' => $user->username,
]);
});
static::deleting(function($user) {
$user->posts()->delete();
});
}

Related

Is there a way to make this query without raw part, between realtion models?

User Model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function venues()
{
return $this->hasMany(Venue::class);
}
public function reviews()
{
return $this->hasMany(Review::class);
}
public function profile()
{
return $this->hasOne(Profile::class);
}
public function approvedVenues()
{
return $this->hasMany(Venue::class)->where('is_approved', '=', 1);
}
public function unapprovedVenues()
{
return $this->hasMany(Venue::class)->where('is_approved', false);
}
public function ownVenuesReviews()
{
return $this->reviews()->whereIn('user_id', function($query) {
$query->select('id')
->from('venues')
->whereRaw('venues.user_id = users.id');
})->get();
}
}
Venue Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Venue extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'city_id',
'category_id',
'title',
'address',
'phone',
'email',
'website',
'facebook',
'instagram',
'content_bg',
'content_en',
'cover_image',
'lat',
'lng'
];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function category()
{
return $this->belongsTo(Category::class, 'category_id');
}
public function city()
{
return $this->belongsTo(City::class, 'city_id');
}
public function features()
{
return $this->belongsToMany(Feature::class, 'venue_feature');
}
public function images()
{
return $this->hasMany(VenueImage::class);
}
public function reviews()
{
return $this->hasMany(Review::class);
}
}
Review Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Review extends Model
{
use HasFactory;
protected $fillable = ['rating', 'content', 'venue_id', 'user_id'];
public function venue()
{
return $this->belongsTo(Venue::class);
}
public function images()
{
return $this->hasMany(ReviewImage::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
So Users have many Venues, Venues have many reviews.
I want to get reviews on own Venues for example (If I own venues with id 100, 101 - I want to get all reviews for these two venues)
Raw query is this:
SELECT * FROM `reviews` WHERE reviews.venue_id IN (SELECT venues.id FROM venues WHERE venues.user_id = 1)
What I tried in Laravel in User model (doesn't work), I'm also curious if there is a way, without raw part:
public function ownVenuesReviews()
{
return $this->reviews()->whereIn('user_id', function($query) {
$query->select('id')
->from('venues')
->whereRaw('venues.user_id = users.id');
})->get();
}
A HasManyThrough relationship should work, if I'm understanding your model relationships properly:
public function ownVenueReviews(): HasManyThrough
{
return $this->hasManyThrough(Review::class, Venue::class);
}
The raw part is only needed because you have to include the foreign key in the select portion of the sub query. Even though you may not want the user_id in the query result it must still be selected for Laravel to be able to make the relationship match work.
public function ownVenuesReviews()
{
return $this->reviews()->whereIn('user_id', function($query) {
$query->select('id', 'user_id')
->from('venues');
})->get();
}
I did it like this, but I'm not quite sure, that this is the best way, I'm open to suggestions:
public function ownVenuesReviews()
{
return Review::whereIn('venue_id', function($query) {
$query->select('id')
->from('venues')
->where('user_id', $this->id);
})->get();
}

Laravel: user id is not added as Foreignkey

I want that a user can create e.g. a football club. When the logged in user creates the club (with an Input-field) the foreignkey should automatically appear in the table of the club.
User
User Modell
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
public function wgGroup()
{
return $this->hasOne('WgGroup','user_id');
}
}
WgGroup e.g. for example to create a club
WgGroup Controller
class WGController extends Controller
{
public function dashboard()
{
return view('verified.dashboard');
}
public function createWG(Request $request)
{
$wg = new WgGroup();
$wg->wg_name = $request->wg_name;
$wg->user_id = User::find($request['id']);
$wg->save();
if($wg != null){
return redirect()->back()->with(session()->flash('alert-success', 'Your wg are createt'));
}
return redirect()->back()->with(session()->flash('alert-danger', 'Something went wrong!'));
}
}
WgGrup Model
class WgGroup extends Model
{
use HasFactory;
protected $table = 'wg_groups';
protected $fillable = [
'wg_name', 'user_id'
];
public function user() {
return $this->belongsTo('User');
}
}
WgGroup Database
class CreateWgGroups extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('wg_groups', function (Blueprint $table) {
$table->id();
$table->string('wg_name');
$table->foreignId('user_id')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('wg_groups');
}
}
I don't know exactly why the FK user_id is not added directly to the database.
public function user() {
return $this->belongsTo('User');
}
I thought through this function would happen.

How to retrieve and display relationship data in Laravel?

I have three tables in the database. orders, products, and order_product table. this is how they look like in my phpmyAdmin https://imgur.com/a/Ud9e2Hh
I would like sellers to see orders placed by buyers in their view (dashboard). Also, buyers to be able to see their orders in their view.
Here are my relationships in models
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'Seller'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
//public function isSeller() {
// return $this->seller;
//}
public function products()
{
return $this->hasMany(Products_model::class);
}
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function orders()
{
return $this->hasManyThrough(Order::class, Products_model::class, 'buyer_id', 'seller_id', 'product_id');
}
public function orderFromBuyers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'seller_id', 'product_id');
}
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'buyer_id', 'seller_id','product_id', 'quantity'];
public function products()
{
return $this->belongsTo('App\Products_model');
}
public function buyer()
{
return $this->belongsTo(User::class, 'id', 'buyer_id');
}
public function seller()
{
return $this->belongsTo(User::class, 'id', 'seller_id');
}
public function order()
{
return $this->belongsTo(Order::class);
}
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
//protected $table = 'orders';
protected $fillable = [
'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone', 'billing_subtotal', 'billing_total',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Products_model')->withPivot('quantity');
}
public function orders()
{
return $this->hasMany('App\OrderProduct', 'order_id');
}
}
Seller Function
// Seller Orders
public function viewOrders(User $user)
{
// $products = Products_model::where('seller_id', '=', $user->id)->get();
// all sells
$sells = $user->orderFromSellers();
dd($sells);
return view('orders')->with(compact('sells'));
}
Buyer Function
//Buyer Orders
public function myOrders()
{
$cart = session();
$orders = Auth::user()->orders;
$orders->transform(function($order, $key) {
dd($orders);
$order->cart = unserialize($order->cart);
return $order;
});
return view('myOrders', ['orders' => $orders]);
}
Right now it shows nothing. Any help on how to solve this will be appreciated.
Products_model
protected $table='products';
protected $primaryKey='id';
protected $fillable=['seller_id','pro_name','pro_price','pro_info','image','stock','category_id '];
Try by changing two function.
public function orderFromBuyers()
{
return $this->hasManyThrough(Products_model::class, OrderProduct::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
return $this->hasManyThrough(Products_model::class, OrderProduct::class, 'seller_id', 'product_id');
}
Or the two will be more better. Add these two functions to User model.
public function allOrderFromBuyers()
{
return $this->hasMany(OrderProduct::class, 'buyer_id');
}
public function allOrderFromSellers()
{
return $this->hasMany(OrderProduct::class, 'seller_id');
}
Then change this to,
// Seller Orders
public function viewOrders(User $user)
{
// all sells
$sells = $user->allOrderFromSellers();
dd($sells);
return view('orders')->with(compact('sells'));
}

Call to a member function create() on null in laravel using Socialite

When I try to authenticate the user with using facebook so I am able to store data into the user table but the failure to create data into the soical_accounts.So after that errors with come up "call to a member funtion create() on null". Can anyone provide me solution that where I am wrong.
In my SocialAccountControll, I have the following method
public function handleProviderCallback($provider)
{
try{
$user = Socialite::driver($provider)->user();
} catch (Exception $e) {
return redirect('/login');
}
$authUser = $this->findOrCreateUser($user, $provider);
Auth::login($authUser, true);
// redirectTo, so that way we use the same redirect location that the rest of our authentication uses.
//This is a normal protected function that you can add in your users table to redirect a user wherever
// you want to set that redirect to.
//return redirect($this->redirectTo);
return redirect('/home');
}
public function findOrCreateUser($socialUser, $provider)
{
$account = SocialAccount::where('provider_name', $provider)->where('provider_id',$socialUser->getId())->first();
if($account)
{
return $account->user;
}
else
{
$user = User::where('email', $socialUser->getEmail())->first();
if(! $user)
{
$user = User::create([
'email' => $socialUser->getEmail(),
'name' => $socialUser ->getName()
]);
}
$user->accounts()->create([
'provider_name' => $provider,
'provider_id' => $socialUser->getId()
]);
return $user;
}
}
In my database migration, I have users and social_accounts and user have one to many relationship with social_accounts.
user table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
Social_accounts table:
public function up()
{
Schema::create('social_accounts', function (Blueprint $table) {
$table->increments('id');
$table->bigInteger('user_id');
$table->string('provider_name')->nullable();
$table->string('provider_id')->unique()->nullable();
$table->timestamps();
});
}
User Model
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function accounts()
{
$this->hasMany('App\SocialAccount');
}
}
SocialAccount Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class SocialAccount extends Model
{
protected $fillable = [
'provider_name', 'provider_id'
];
public function user() {
return $this->belongsTo('App\User');
}
}
You are not returning anything here so change:
public function accounts()
{
$this->hasMany('App\SocialAccount');
}
To
public function accounts()
{
return $this->hasMany('App\SocialAccount');
}

Trying to get property of non-object in laravel 5.2

this is my posts table
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('prf_id')->unsigned();
$table->foreign('prf_id')->references('id')->on('profiles')->onDelete('cascade');
$table->longText('status');
$table->timestamps();
});
}
public function down()
{
Schema::drop('posts');
}
}
this my Post model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table='posts';
protected $fillable = ['status'];
protected $hidden = [];
public function profile(){
return $this->belongsTo('App\Profile');
}
public function user(){
return $this->belongsTo('App\User');
}
}
this is profile model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
protected $table='profiles';
protected $fillable = ['user_id','name','position','roles','username','college','phone','location','graduation','skill'];
protected $hidden = [];
public function posts(){
return $this->hasMany('App\Post');
}
}
this is User model
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $fillable = [
'fname','lname', 'email','sex', 'password','user_id','roles'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function posts(){
return $this->hasMany('App\Post');
}
}
when i try {{$status->user->fname}} this.its show the correct value but when i try {{$status->profile->username}} this ,every time it shows me Trying to get property of non-object (View: C:\xampp\htdocs\abc\resources\views\pages\profile.blade.php)
i really don't know why :(
In your Post class try the following code:
public function profile(){
return $this->belongsTo('App\Profile', 'prf_id');
}

Categories