How to get pivot data depends model binding - laravel

I am using in Pivot model. In previously i assigned user_id is routekey but now i want to match model binding flats (flat_id) also. I have attached the output screenshot too.
My url is http://127.0.0.1:8000/admin/apartments/1/flats/2/flat-members/3
namespace App\pivotes;
use Illuminate\Database\Eloquent\Relations\Pivot;
use App\models\RoleUser;
use App\models\Flat;
use App\models\Association;
use App\models\Role;
use App\User;
class FlatUser extends Pivot
{
protected $table = 'flat_user';
public $timestamps = false;
public function getRouteKeyName()
{
return 'user_id';
}
public function flat()
{
return $this->belongsTo(Flat::class, 'flat_id', 'id');
}
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function role()
{
return $this->belongsTo(Role::class, 'role_id', 'id');
}
}
Update I tired this
In RouteServiceProvider
public function boot()
{
parent::boot();
Route::bind('flat_member', function ($value) {
dd(\App\pivotes\FlatUser::where('flat_id', request()->route()->parameter('flat'))->where('user_id', request()->route()->parameter('flat_member'))->first());
return \App\pivotes\FlatUser::where('flat_id', request()->route()->parameter('flat'))->where('user_id', request()->route()->parameter('flat_member'))->first() ?? abort(404);
});
}
for dd() I am getting correct data, but if I am returning it, it seems to be becoming empty.

I am using RouteServiceProvider.php. I check flat_id and route parameter flats whether it matches, giving particular pivot model data. In below added my codes.
public function boot()
{
parent::boot();
Route::bind('flat_member', function ($value) {
return \App\pivotes\FlatUser::where('flat_id', request()->route()->parameter('flat'))->where('user_id', request()->route()->parameter('flat_member'))->first() ?? abort(404);
});
}

Related

Retrieve all elements on laravel collection

I've just started using Laravel. I'm currently creating some sort of "Instagram" app as an example. So I have 4 tables. Users, Images, Comments and Likes. I've already created the "Models" using the php artisan command make:model and included some data to the database. The thing is, after creating the relationships of the models like.
use App\Image;
class Comment extends Model
{
protected $table = 'comments';
protected $primaryKey = 'CommentId';
public function user()
{
return $this->belongsTo('App\User', 'UserId');
}
public function image()
{
return $this->belongsTo('App\Image', 'ImageId');
}
}
And doing the same thing on the Image Model
class Image extends Model
{
protected $table = 'images';
protected $primaryKey = 'ImageId';
public function comments()
{
return $this->hasMany('App\Comment', 'CommentId');
}
public function likes()
{
return $this->hasMany('App\Like', 'LikeId');
}
public function user()
{
return $this->belongsTo('App\User', 'UserId');
}
I can't get all the comments on an image, after executing:
Route::get('/', function () {
$images = Image::all();
foreach ($images as $image) {
echo "Uploaded By: ".$image->user->FirstName."<br>";
echo "<strong>Comments</strong><br>";
foreach ($image->comments as $comment)
{
echo "Comment: ".$comment->Content;
}
}
die();
return view('welcome');
});
I can only get one element on each image, even though the image has more than 1 comment.
i think the problem is in your comments relation:
public function comments()
{
return $this->hasMany('App\Comment', 'CommentId');
}
it should be:
public function comments()
{
return $this->hasMany('App\Comment', 'ImageId');
}
the second parameter in hasMany relation should be the foreign key that relate the two table in data base.
more details in:
https://laravel.com/docs/7.x/eloquent-relationships#one-to-many

simple One to many relationship laravel

i have a user(ADMIN) and a student i want them to be in one table that is on the dashboard controller i cant find and exact answer in the searching please help me
Student model
public function user()
{
return $this->belongsTo("App\User", 'User_id', 'id');
}
User model
public function student()
{
return $this->hasMany("App\Student");
}
DashboardController
$users = User::with('user_id');
return view('superadminpage.admin_table')->with('users', $users);
Edit Student model code like this:
public function user(){
return $this->belongsTo("App\User");
}
Also edit User model:
public function students(){
return $this->hasMany("App\Student");
}
then use in DashboardController
$users = User::query()->with("students")->all();
return view('superadminpage.admin_table')->with('users', $users );
then you can do this:
foreach($users as $user){
$students = $user->students;
// use
}
first change the User_id to user_id at student model
public function user()
{
return $this->belongsTo("App\User", 'user_id');
}
second change at DashboardController
$users = User::with('user_id'); to $users = User::with('student')->all();
first change the User_id to user_id at student model
public function user()
{
return $this->belongsTo("App\User", 'user_id' , 'id');
}
second change at DashboardController
$users = User::with('user_id'); to $users = User::with('student')->all();
it's also good to change at user model public function student() to public function students() and call at DashboardController $users = User::with('students')->all();
public function users()
{
return $this->hasMany('App\User');
}
public function role()
{
return $this->belongsTo('App\Role');
}

how to use laravel Scope in a relationship?

I'm using laravel
I have two models
Product
class Product extends Model
{
public function productcategories(){
return $this->hasOne('App\Product\Productcategorie','CategoryID','ProductCategoryId');
}
}
and Productcategorie
class Productcategorie extends Model
{
protected $primaryKey = 'CategoryID';
public function product(){
return $this->belongsToMany('App\Product\Product','ProductCategoryId','CategoryID');
}
public function scopeCp($query,$id){
return $query->where('categoryparent_id', '=', $id);
}
}
The Product model has a scope Cpscope
and i have ProductController with function
function productCatgoryPaFilter(Request $request){
$categories= Categoryparent::with('categories')->get();
$id=$request->id;
return $product = Product::with('productcategories')->with('productoption.option')->orderBy('created_at','DESC')->get();
}
i want to get all products with categoryparent_id equal to passed parametre in scope
how can i do it?
If you want to filter data in relational model, use whereHas(). Though i have not tested, give it a try
Product::whereHas('productcategories', function ($query) use($id) {
$query->cp($id);
})
->orderBy('created_at','DESC')->get()

type casting in laravel json response in relationships eager loading

This is my post model.
class Post extends Model
{
use SoftDeletes;
protected $table = 'posts';
protected $fillable = ['title','featuring_image', 'brief', 'body', 'seen_count'];
public function user(){
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function someComments()
{
return $this->comments()->limit(Constants::COMMENTS_COUNT_LIMIT);
}
public function commentsCount()
{
return $this->comments()
->selectRaw('post_id, count(*) as count')
->groupBy('post_id');
}
public function likes()
{
return $this->hasMany(Like::class);
}
public function isLiked()
{
return $this->likes()->where('user_id', auth()->check() ? auth()->user()->id : 0);
}
public function likesCount()
{
return $this->likes()
->selectRaw('post_id, count(*) as count')
->groupBy('post_id');
}
}
I executed this query on this model.
$post = Post::with(['categories', 'user', 'commentsCount', 'likesCount', 'isLiked'])->find($post->id);
Because of the relation between this table and like and comment table, The output of this query for 'commentsCount', 'likesCount', 'isLiked' is an array. But I need to receive numbers for 'commentsCount' and 'likesCount', and a boolean for 'isliked' as an output, in laravel josn response.
You might find it easier to use the withCount() the comes with Eloquent instead.
Then for is_liked you could use a scope to get the value and the cast it to a boolean:
public function scopeIsLiked($query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->likes();
});
$q = $this->likes()->getRelationExistenceCountQuery(
$relation->getRelated()->where('user_id', auth()->check() ? auth()->user()->id : 0)->newQuery(), $query
);
$query->selectSub($q->toBase(), 'is_liked');
}
Please note you will need to add the use statement for Relation to the top of the class:
use Illuminate\Database\Eloquent\Relations\Relation;
You model could then look like:
class Post extends Model
{
use SoftDeletes;
protected $table = 'posts';
protected $fillable = ['title', 'featuring_image', 'brief', 'body', 'seen_count'];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function someComments()
{
return $this->comments()->limit(Constants::COMMENTS_COUNT_LIMIT);
}
public function likes()
{
return $this->hasMany(Like::class);
}
/**
* Scope to add the "is_liked" flag.
*
* #param $query
*/
public function scopeIsLiked($query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->likes();
});
$q = $this->likes()->getRelationExistenceCountQuery(
$relation->getRelated()->where('user_id', auth()->check() ? auth()->user()->id : 0)->newQuery(), $query
);
$query->selectSub($q->toBase(), 'is_liked');
}
}
And your query would look something like:
$post = Post::with('categories', 'user')
->withCount('likes', 'comments')
->isLiked()
->find($post->id);
Hope this helps!
You can use Laravel casts:
Inside the each model you can add the following to cast a value, per example:
protected $casts = [
'isLiked' => 'boolean',
];
Rwd's answer gives a nice solution using scopes, but for laravel 5.4+ you could get away with aliasing the withCount() result and then casting it to boolean with a $cast variable on the model or an accessor (with accessor, you can only get snake case is_liked). This way we don't need to write complex scopes.
The model would be
class Post extends Model
{
// rest of model
protected $casts = ['isLiked'=>'boolean'];
public function likes()
{
return $this->hasMany(Like::class);
}
}
Then in your controller
$post = Post::with('categories', 'user')
->withCount(
[
'likes as likesCount', 'comments as commentsCount',
'likes as isLiked' =>function($query){
$query->where('user_id', auth()->check() ? auth()->user()->id : 0);
}
]
)
->find($post->id);
And now you get likesCount (int), commentsCount (int) and isLiked (boolean)

Laravel scout check if relation is not empty?

namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
class Event extends Model
{
protected $table = 'events';
public $timestamps = true;
use Searchable;
use SoftDeletes;
protected $dates = ['deleted_at'];
public function entities()
{
return $this->belongsTo('App\Entity', 'entity_id');
}
public function users()
{
return $this->belongsTo('App\User', 'id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'id');
}
public function toSearchableArray()
{
$data = $this->toArray();
$data['entities'] = $this->entities->toArray();
return $data;
}
}
This is my model for Event, as you can see I am using toSearchableArray which is Laravel scout function to import 'relations' to algolia. However the problem is that sometimes it is empty. So for example
event id 1 has entity_id 1
but in another example
event id 2 has entity_id = null
How can I modify this function to check if the entities() relation is not empty before putting it into array?
if i understand u correctly this should help. if the relationship does not exist return an empty array and scout won't update the index
public function toSearchableArray()
{
if(is_null($this->entities)){
return [];
}
$this->entities
return $this->toArray();
}
please update foreign_key in relation as this
user_id as foreign_key instead of id
event_id as foreign_key instead of id
public function users()
{
return $this->belongsTo('App\User', 'user_id');
}
public function events()
{
return $this->belongsTo('App\DirtyEvent', 'event_id');
}
I think if load the relation before the toArray().
public function toSearchableArray()
{
$this->entities;
return $this->toArray();
}

Resources