I have the below tables and I want to retrieve the number of each comment likes with users that liked the comment (something like Instagram comment which any body can like another user comments)
users table
id
name
Asks table
id
title
comments table
id
ask_id
user_id
text
comment_like table
id
comment_id
user_id
it used for saving comment links, it looks like Instagram comment which any user can like another user comment.
here is my User Model Code:
class User extends Authenticatable
{
public function comments_like()
{
return $this->belongsToMany(
Comment::class,
'comment_like' ,
'user_id' ,
'comment_id' ,
'id',
'id'
);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
here is my Ask Model Code:
class Ask extends Model
{
use HasFactory;
protected $table = 'asks';
protected $fillable = ['title'];
public function comments()
{
return $this->hasMany(Comment::class);
}
}
here is my User Model Code:
class User extends Authenticatable
{
public function comments_like()
{
return $this->belongsToMany(
Comment::class,
'comment_like' ,
'user_id' ,
'comment_id' ,
'id',
'id'
);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
here is my Comment Model Code:
class Comment extends Model
{
//user relation
public function user()
{
return $this->belongsTo(User::class);
}
//ask relation
public function ask()
{
return $this->belongsTo(Ask::class);
}
//comment_like relation
public function users_like ()
{
return $this->belongsToMany(
User::class ,
'comment_like',
'comment_id',
'user_id',
'id',
'id'
)
->withTimestamps();
}
//condition on comment_like relation
public function user_like_byId($id)
{
return $this->belongsToMany(
User::class ,
'comment_like',
'comment_id',
'user_id',
'id',
'id'
)
->where('id',$id)->get();
}
}
I want to retrieve latest ask with their comments which include count and data of comment_like**
I used this code but it show error
$ask= Ask::query()->latest('id')->get()->first();
foreach ($ask->comments()->get() as $commentItem) {
echo "id: ".$commentItem->id .'<br>';
echo "name :" .$commentItem->user()->pluck('name')[0] . "<br>";
echo "text :" .$commentItem->text . "<br>";
echo $commentItem->user_like_byId($commentItem->id);
}
You can create a resource with php artisan make:resource AskResource for your fetched data and use count() function for get length of data.
Related
Hi I am developing an api in laravel for an online course system. In this scheme I have a standard table for users, a table for courses and a pivot table that relates courses and users according to which they sign up for each course.
This last table also carries the events related to the progress of each user in the course, that is, Subscribed, Progress x%, Completed, Approved, so that each user can have multiple entries in the course_users table.
So far everything is clear and everything is fine, the point is that at a certain moment I need to return a json object with the information of the courses and pointed users, this can be clearly achieved using resource collection in the following way:
CourseCollection.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
use App\Http\Resources\CargoResource;
class CourseCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'data' => CourseResource::collection($this->collection),
'links' => [
'self' => 'link-value',
],
];
}
}
CourseResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CourseResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title'=> $this->title,
'description'=> $this->description,
'price'=> $this->price,
'users' => CourseUserResource::collection($this->whenLoaded('users'))
];
}
}
CourseUserResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CourseUserResource extends JsonResource
{
public function toArray($request)
{
return [
'course_id'=> $this-> course_id,
'user_id'=> $this->user_id,
'event'=> $this->event,
'event_date' => $this->created_at->format('Y-m-d')
];
}
}
The problem to be solved is that with this scheme I obtain a collection of events for each user and course, but what I am needing is only the last event of each user, to know what their status is in relation to the course.
I am analyzing the option to perform the query by sql and then manually build the json object, but I would like to have a "laravel style" solution
Any ideas will be welcome!
Added Models & Controllers for clarification
class Course extends Model
{
protected $fillable = [
'title',
'slug',
'description',
'course_category_id',
'price',
'published'
];
...
public function history()
{
return $this->belongsToMany(CourseUser::class, 'course_id', 'id')->latest();
}
public function scopePublished($query)
{
return $query->where('published', 1);
}
}
class CourseUser extends Model
{
protected $fillable = [
'course_id',
'user_id',
'event'
];
}
class SearchController extends ApiController
{
public function search(Request $request)
{
$results = Course::with('history')
->published
->where('title', 'like', $request->filter['title'])
->where('description', 'like', $request->filter['description'])
->get();
if (! count($results) > 0) {
return $this->sendResponse(
__('No results for your query.'),
[
'code'=>204,
'message'=> __('There are no results for your search criteria.')
],
204
);
}
return new CourseCollection($results);
}
}
I need how to show data in another table like MySQL join or something like that
MySQL example
My Code
Model usuarios
class Usuario extends Model {
protected $table = 'usuarios';
protected $primaryKey = 'idusuarios';
protected $filliable = [
'cedula', 'nombre', 'tele1', 'tele2', 'correo', 'direccion',
'user_name', 'user_pass', 'fecha_ingreso', 'usu_idrol'
];
public function Usuario() {
return $this->hasOne('app\Roles','idrole','usu_idrol','desc_rol');
}
const CREATED_AT = NULL;
const UPDATED_AT = NULL;
}
Model Roles
class Roles extends Model {
protected $table ='roles';
protected $primarykey = 'idrole';
protected $filliable = ['desc_rol'];
public function Roles() {
return $this->belongsTo('app\Usuario', 'usu_idrol', 'idrole');
}
}
Controller usuarios
public function index(Request $request) {
if (!$request->ajax()) return redirect('/');
$usuarios = Usuario::all();
return $usuarios;
}
View usuarios
that's what I need
Try this in the controller that is returning data to your vue instance
//get all the users from the database (in your controller)
//you need to create a new array so as to easily map the role in the returned results
return Usuario::with('Usuario')->get()->map(function($role) {
return [
'field1' => $role->field1,
'field2' => $role->field2,
'field3' => $role->field3,
'field4' => $role->field4,
'field5' => $role->field5,
'rol' => $role->Usuario->desc_role
];
});
i have created an auto complete search box in controller of 'booking' table successfully , but i want the auto complete search box to show data from another table 'patient' that have a one to many relationship with "booking" table according to a specific condition using 'where' condition ,
This is the Booking Controller that i add autocomplete in it:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Booking;
use App\Patient;
use App\User;
use Session;
use DB;
use Auth;
use Input;
class BookingController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$search = \Request::get('search');
$bookings = Booking::whereHas('patient', function ($query) use ($search) {
$query->where('patient_name', 'like', '%' . $search . '%');
})->where('status','=', null)->whereHas('patient', function ($query){
$query->where('company_id','=' ,Auth::user()->company_id);
})->paginate(10);
return view('booking.index')->withBookings($bookings);
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function autoComplete(Request $request) {
$query = $request->get('term','');
$bookings=Booking::whereHas('patient', function ($query){
$query->where('company_id','=' ,Auth::user()->company_id);
})->$data=array();
foreach ($bookings as $booking) {
$data[]=array('value'=>$booking->patient->patient_name,'id'=>$booking->id);
}
if(count($data))
return $data;
else
return ['value'=>'No Result Found','id'=>''];
}
and this is the Booking Model :
class Booking extends Eloquent
{
public function patient()
{
return $this->belongsTo('App\Patient');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
and this is the patient Model:
class Patient extends Eloquent
{
public function booking()
{
return $this->hasMany('App\Booking');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
and i used this code in view :
{!! Form::text('search_text', null, array('placeholder' => 'Search Text','class' => 'form-control','id'=>'search_text')) !!}
i want to show data from "patient" table and there is a one to many relationship between "booking" and "patient" table and i have successfully made a search box to search in patient table as you can see in index function , but i dont know to show data from "patient" table using where condition to show patient_name that his company_id equal Authenticated user company_id
Sorry for my Bad Language .
I have a Model called User and another Model called Roles and they are linked with each other through a belongsToMany relationship. But I needed to cast certain pivot attributes so I used a custom pivot class RoleUserPivot which basically looks like follows:
...
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleUserPivot extends Pivot
{
protected $casts = [
'active' => 'boolean',
'permissions' => 'array',
];
}
...
The relationship definition in User and Role models is as follows:
...
// User Model
public function roles()
{
return $this
->belongsToMany('App\Role')
->withPivot(
'active',
'permissions'
);
}
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
if ($parent instanceof Role) {
return new RoleUserPivot($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
...
And similarly:
...
// Role Model
public function users()
{
return $this
->belongsToMany('App\User')
->withPivot(
'active',
'permissions'
);
}
public function newPivot(Model $parent, array $attributes, $table, $exists)
{
if ($parent instanceof User) {
return new RoleUserPivot($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
...
The problem I am having is, while the active field is properly cast to boolean, the permissions field is not cast to array, instead the same string in the database is returned. I assure that the pivot table is properly setup and permissions column is MySQL TEXT column.
Currently I am using Laravel 5.1.16 (LTS).
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);
));
}