I've this query:
I'm building a forum and I would like to show the latest message that has being posted. I'm doing that like this:
return Forum::with(['users' => function($query){
$query->select('user.id', 'user.name', 'user.last_name')
}]);
forum model:
/**
* #return mixed
*/
public function users()
{
return $this->belongsToMany(User::class, 'message');
}
How do I only receive the latest user. Right now I receive them all.
Thanks a lot!
public function users()
{
return $this->belongsToMany(User::class, 'message')->orderBy('id', 'desc');
}
If you want to limit the number of users returned, append ->take(10); to take only last 10 users
Related
I am using laravel 5.6 and i want to get user posts with comments (only id field)
User Model
public function posts()
{
return $this->hasMany('App\Post');
}
Post Model
public function user()
{
return $this->belongsTo('App\User');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
Comment Model
public function post()
{
return $this->belongsTo('App\Post');
}
In my controller i am using this code to get user posts with their comments
$posts = $request->user()->posts()->with(['comments' => function($query) {
$query->select(['id']);
}]);
But its not working...
When i comment $query->select(['id']); it works fine but returns Comment model all fields. I want to only select id field.
What i am missing here?
You also have to select the foreign key column (required for matching the results):
$posts = $request->user()->posts()->with('comments:id,post_id');
If you want to only one column, you can use ->pluck('id')
https://laravel.com/docs/5.6/collections#method-pluck
I have two models, User and Post
User Model:
public function posts()
{
return $this->hasMany('App\Post');
}
Post Model:
public function user()
{
return $this->belongsTo('App\User');
}
In my controller I have a public function which has:
$users = User::orderBy('is_ban', 'desc')->paginate(10);
$posts = Post::orderBy('created_at', 'desc')->paginate(10);
Which is working as expected.
I also have one column in users table `is_ban' It's of boolean type.
I am looking for a query which will return the following:
Only get post which has been made by the user which has is_ban=false
perhaps i haven't understood you, but i hope it will help. You can add it to your Post model
public function getBannedUsersPosts()
{
return self::whereIn('user_id', User::where('is_ban', 0)->pluck('id'))->get();
}
I can't seem to get the syntax right for this query.
Basically, I have a product that is listed, where an offer is made by a user:
So in Offer.php
public function user()
{
return $this->belongsTo('App\User', 'buyer_id');
}
public function product(){
return $this->belongsTo('App\Product');
}
And in User.php
public function offers()
{
return $this->hasMany('App\Offer', 'buyer_id');
}
Then in Product.php
public function offer()
{
return $this->hasMany('App\Offer');
}
I need to group offers by the user that has made them, and then group that again by the category of the product the offer is against.
Does anyone have ideas where I can start to group these correctly?
Try with Query Builder. Like this ( I don't know your tables`s structure):
$offers = DB::table('offers')
->joinLeft('users','users.id','=','offers.buyer_id')
->joinLeft('products','products.id','=','offers.product_id')
->groupBY('users.id','products.category_id')
->get();
I've got this query in Laravel:
return Forum::with(['users' => function($query){
$query->select('user.id', 'user.name', 'user.last_name');
}])->latest()->withCount('messages')->paginate(10);
This returns all users that have posted a message in a forum.
On my forum model I've these relations:
public function users()
{
return $this->belongsToMany(User::class, 'message');
}
public function messages()
{
return $this->hasMany(Message::class);
}
I would like to receive only the latest user that has posted a message. How could I do this?
You can retrieve the last user by messages relationship, try this:
return Forum::with(['messages' => function($query){
$q->orderBy('created_at', 'desc');
},'messages.users'])->first();
Use has() method and order by created_at in descending order.
User::has('forums.messages')->orderBy('created_at','desc')->first();
I can't find solution how to retrieve links that belongs to user where campaign is active?
Here are my models:
User model:
public function links(){
return $this->hasMany('Link','user_id');
}
public function analytic(){
return $this->hasManyThrough('Analytic','Link');
}
Campaign model:
public function task(){
return $this->hasMany('Task','campaign_id');
}
public function links(){
return $this->hasManyThrough('Link','Task');
}
Task model:
public function campaign(){
return $this->belongsTo('Campaign','campaign_id');
}
public function links(){
return $this->hasMany('Link','task_id');
}
public function analytic(){
return $this->hasManyThrough('Analytic','Link');
}
Link model:
public function task(){
return $this->belongsTo('Task','task_id');
}
public function user(){
return $this->belongsTo('User','user_id');
}
public function analytic(){
return $this->hasMany('Analytic','link_id');
}
So, admin creates a campaign and task that belongs to campaign and users can start task, once they start task they are getting their link assigned for that task and campaign.
In this case I can easily count all user links:
$user = User::find(1);
echo $user->links->count();
But my question is how to echo only links that are related to active campaigns.
Again: CAMPAIGN has many TASK, TASK has many LINKS, USER has many LINKS.
Get the number of links that belongs to user only for active campaigns.
Similar thing with analytics :(
Every link has many analytics ( tracking clicks )
Analytic model:
public function links(){
return $this->belongsTo('Link','link_id');
}
Also need to echo the count of links only for tasks that are under active campaign.
First off, you don't need to run query for a user if you have his id:
$user=User::find($id); // redundant
// instead
Link::where('user_id', $id)->count();
Now to get those links for active campaigns:
Link::whereHas('task', function ($q) {
$q->whereHas('campaign', function ($q) {
$q->active(); // or where('status', 'active'); see below
});
})->where('user_id', $id)->get();
// of course you can start with $user->links()->whereHas ... instead
My example covers scope for a campaign:
// Campaign model
public function scopeActive($query)
{
$query->where('status', 'active');
}
The same goes for count:
Link::whereHas('task', function ($q) {
$q->whereHas('campaign', function ($q) {
$q->active();
});
})->where('user_id', $id)->count();
You can wrap that whereHas chain in a scope as well:
// Link model
public function scopeOnlyActiveCampaigns($query)
{
$query->whereHas('task', function ($q) {
$q->whereHas('campaign', function ($q) {
$->active();
});
});
}
// then simply:
Link::onlyActiveCampaigns()->where('user_id', $id)->count();
And as stated in the comment: use consistent names for relations, it will make your life easier:
$link->analytic; // collection, better analytics
$analytic->links; // single Link model, better link etc