First , i'm sorry for my english.
I have two tables: Users
class Users extends Model {
public function posts(){
return $this->hasMany('App\posts','user_id');
}
}
and posts
class posts extends Model{
public function users(){
return $this->belongsTo('App\Users','user_id');
}
}
Each users has many posts.
I want take only 4 posts of each users.
I tested this code, but it does not work.
Users::with(['posts'=>function($query){
return $query->skip(0)->take(4);
}])->get();
You can't limit results on eager loads
However, you can run it like this:
return Users::with('posts')->get()->map(function ($users) {
$users->posts = $users->setRelation('posts', $users->posts->take(4));
return $users;
});
Related
I have a table like this:
Basically this table is named favourite_products and contains product ids that are added as favourite for users.
Now I wanted to get a collection of most added product from this table.
So in this case, a product with an id of 10 would be on top of the collection.
But I don't know how to get this collection ordering by from most repeated product id (prd_id)...
Here is the Model:
class FavouriteProduct extends Model
{
protected $table = 'favourite_products';
protected $fillable = ['usr_id','prd_id'];
public function user()
{
return $this->belongsTo(User::class, 'usr_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'prd_id');
}
}
UPDATE #1:
Product.php Model:
public function favouritees()
{
return $this->belongsToMany(User::class, 'favourite_products', 'prd_id', 'usr_id');
}
I think the following code solve your problem:
$most_liked_products = DB::table('favourite_products')
->select(DB::raw('count(prd_id) as total'), id)
->groupBy('total')
->orderByDesc('total')
->get();
Please try it and give your feedback
try use this
public function example()
{
$data=FavouriteProduct::orderBy('prd_id', 'ASC')->get();
dd($data);
}
I have a database setup where you have a lecturer having many groups and each group having many students and also a student can be in many groups. Therefore I have a one to many relationship between a lecturer and groups (respectively) and a many to many relationship between students and groups.
I want to show the lecturer how many students they have overall. For example if the lecturer has 5 groups with 5 students in each then I want to show 25. I tried this auth()->user()->userable->groups()->withCount('students') but I got this:
Call to a member function getRelationExistenceCountQuery() on null
Edited, Here are the relationships:
# user model
class User extends Authenticatable{
public function userable(){
return $this->morphTo();
}
}
# staff/lecturer model
Staff extends Model {
public function user(){
return $this->morphOne(User::class, 'userable');
}
public function groups(){
return $this->hasMany(Group::class);
}
}
#group model
class Group extends Model {
public function staff(){
return $this->belongsTo(Staff::class);
}
public function students(){
$this->belongsToMany(Student::class, 'groups_students', 'group_id');
}
}
# student model
class Student extends Model {
public function groups(){
return $this->belongsToMany(Group::class, 'groups_students', 'student_id');
}
}
What's the most efficient way to get my desired result?
Group::students() is missing the return statement:
public function students(){
return $this->belongsToMany(Student::class, 'groups_students', 'group_id');
^^^^^^
}
You can get the total of number of students like this:
$groups = auth()->user()->userable->groups()->withCount('students')->pluck('students_count');
$count = $groups->sum();
I have two tables: assessments and benchmarks. benchmarks has a field called content. There is a many to many relationship between them: assessment_benchmark. I want to sort a collection of records from the assessment_benchmark table by the content attribute of the corresponding benchmark. I have tried:
$sorted = AssessmentBenchmark::all()->sortBy(function($assessmentBenchmark){
return $assessmentBenchmark->benchmark->content;
});
But this just does not work (it just returns the original order). However, when I return $assessmentBenchmark->comment for example, it does work (comment is a field in assessment_benchmark).
The models look like this:
class AssessmentBenchmark extends Model
{
public function benchmark()
{
return $this->belongsTo(Benchmark::class);
}
public function assessment()
{
return $this->belongsTo(Assessment::class);
}
}
class Benchmark extends Model
{
public function assessments()
{
return $this->belongsToMany(Assessment::class);
}
}
class Assessment extends Model
{
public function benchmarks()
{
return $this->belongsToMany(Benchmark::class);
}
}
Well, you can use below query for sorting, I'm gonna use Assessment model, because, I'm never use pivot modal before. Actually, I never had pivot model..
$assessments = Assessment::with(["benchmarks"=>function($query){
$query->orderBy("content","DESC");
}])
With method aşso provide you eagerloading, so when you put $assessments in iteration , you won't make new query for each relation
From chat discussion, it found that you have pivot field and for that you can change your belongsToMany relationship like this
class Benchmark extends Model
{
public function assessments()
{
return $this->belongsToMany(Assessment::class)->withPivot('comment','score')->withTimestamps();
}
}
class Assessment extends Model
{
public function benchmarks()
{
return $this->belongsToMany(Benchmark::class)->withPivot('comment','score')->withTimestamps();
}
}
Now fetch data
$assessment = Assessment::with(['benchmarks' => function($query){
$query->orderBy('content', 'desc');
}])->find($assessmentId);
In view you can render it like this
#foreach($assessment->benchmarks as $benchmark)
<tr>
<td>{{$benchmark->id}}</td>
<td>{{$benchmark->name}}</td>
<td>{{$benchmark->pivot->score}}</td>
<td>{{$benchmark->pivot->comment}}</td>
</tr>
#endforeach
For update you can use updateExistingPivot
For details check ManyToMany relationship https://laravel.com/docs/5.6/eloquent-relationships#many-to-many
I searched a lot but could not find any answer about it, so I hope you could help me!
I have three tables: posts, users and post_users.
Post_users contains two columns: user_id and post_id.
I need to get all posts by an user with Eloquent. Any ideas?
Model User:
public function posts()
{
return $this->belongsToMany('App\Post', 'post_users', 'user_id', 'post_id');
}
Model Post:
public function users()
{
return $this->belongsToMany('App\User', 'post_users', 'post_id', 'user_id');
}
Try:
$user = User::find($id);
$allpost = $user->posts()->get();
var_dump($allpost);
The Laravel docs cover this pretty well but I had an issue with it when I first started as well. Check out Laravel Relationships for the fully write up.
// Inside your Post model
public function user() {
return $this->belongsTo('App\User');
}
// Inside your User model
public function posts() {
return $this->hasMany('App\Posts');
}
You can then create a query:
$posts = User::find(1)->posts;
Or you can filter it further..
$posts = User::find(1)->posts()->where('active', 1)->get();
You may need to change your paths for the hasMany() and belongsTo() if your model location and names are different.
As you wish. Relation between User and Post is many-to-many
- Defined relation
// In User model
public function posts(){
return $this->belongsToMany(Post::class);
}
// In Post model
public function users(){
return $this->belongsToMany(User::class);
}
- Table structure
- users
id
- posts
id
- post_user
user_id
post_id
- Get all post by a user
$posts = User::find($user_id)->posts
If you donot have relationship built, try this. However building relationships is preferred. PostUsers and Posts are assumed models of post-users and posts tables, and post as column of the posts table. this gives the posts of logged in user, but not tested.
$postusers=PostUsers::where(['user_id'=>Auth::user()->id])->get();
foreach($postusers as $postuser)
{
$posts=Posts::where(['post_id'=>$postuser->post_id)]->get();
foreach($posts as $post)
{
print_r($post->post);
}
}
Try this
From Controller :
dd(Auth::user()->posts);
App/User
public function posts()
{
return $this->belongsToMany('App\Entities\posts', 'post_users', 'user_id', 'post_id');
}
make relationship with post model on the user model:
public function posts()
{
return $this->hasMany(Post::class);
}
make relationship with user model on the post model:
public function User()
{
return $this->belongsTo(User::class);
}
in controller or Wherever you use:
$userPosts = User::find($user->id)->posts->where('status', 1);
I built a commenting system, and I'm working on a page that shows all the comments that are waiting for approval.
The relationship:
Article.php
public function comments()
{
return $this->hasMany('App\ArticleComment');
}
ArticleComment.php
public function article()
{
return $this->belongsTo('App\Article');
}
Now, I want to select only the articles that have comments that are waiting for approval (status column on article_comments table equals 0).
Any easy way of doing it? (Of course I can get all articles and check on each one if it has comments)
The other answer will work but you asked for an easy (also re-usable) approach to use so I would suggest to create a scope method in your ArticleComment model using something like the following:
In your Article model:
use App\ArticleComment;
use Illuminate\Database\Eloquent\Model;
class Article extends Model {
// Relation for comments
public function comments()
{
return $this->hasMany(ArticleComment::class);
}
// Relation for pending comments
public function pendingComments()
{
return $this->comments()->pending();
}
}
In your ArticleComment model:
// Query scope for pending comments
public function scopePending($query)
{
$query->whereStatus(0);
}
So, you can use something like this:
$posts = Post::has('pendingComments')->get();
Also, you may chain with like:
$posts = Post::has('pendingComments')->with('pendingComments')->get();
$articles = Article::whereHas('comments', function($query) {
$query->where('status', 0);
})->get();