Laravel - my scope method does not appear to be working - php

I am using scope to filter conditions for specific users, I have assigned a course to a teacher and when this teacher signs into their account, I only want this teacher to view their course, although my scope method doesn't appear to be working correctly. I am not getting an error, so I am not sure where I have gone wrong. I have added some of my code below, i would be very grateful for any help. Thanks
CoursesController index method;
public function index()
{
$courses = Course::ofTeacher()->get();
return view('admin.courses.index')->with('course', $courses); //pass data down to view
}
Course.php;
<?php
namespace App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
class Course extends Model
{
protected $fillable = [
'id', 'title'
];
public function courses(){
return $this->belongsToMany('App\User');
}
public function teachers() {
return $this->belongsToMany(User::class, 'course_user')
}
public function scopeOfTeacher($query)
{
if (!Auth::user()->isAdmin()) {
return $query->whereHas('teachers', function($q) {
$q->where('user_id', Auth::user()->id);
});
}
return $query;
}
}
User.php;
public function isAdmin() {
return $this->role()->where('role_id', 1)->first();
}

Related

Accessing a hasMany relation function via Collection

I am trying to get all of the users notifications, and depending on if the user is a buyer or seller (can be both). I have made two functions in my notifications table to filter each other out.
My goal is to ultimately run:
$notifications = Auth::user()->notifications()->getBuyerNotifications();
or
$notifications = Auth::user()->notifications()->getSellerNotifications();
I am running into an issue: Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany
User Model:
public function notifications() {
return $this->hasMany('App\Notification', 'user_id', 'id');
}
Notifications Model:
public function user() {
return $this->belongsTo('App\User', 'id', 'user_id');
}
public static function getBuyerNotifications() {
return self::whereNotNull('buyer_id')
->whereNull('deleted_at')
->get();
}
public static function getSellerNotifications() {
return $this->whereNotNull('seller_id')
->whereNull('deleted_at')
->get();
}
The command I want to run to get all of the users notifications if they're a buyer: $notifications = Auth::user()->notifications()->getBuyerNotifications();
Firstly, you don't need to use whereNull('deleted_at'), you can import the softDeletes Trait in your model:
use Illuminate\Database\Eloquent\SoftDeletes;
...
class Notification extends Model {
use SoftDeletes;
...
}
Laravel will automatically use whereNull('deleted_at') on Eloquent-Builder.
Secondly, you cannot use static method on Illuminate\Database\Eloquent\Relations\HasMany.
Use scope method instead:
public function scopeBuyerNotifications($query) {
return $query->whereNotNull('buyer_id');
}
public function scopeSellerNotifications($query) {
return $query->whereNotNull('seller_id');
}
So you can find the notification like this:
$notifications = Auth::user()->notifications()->sellerNotifications()->get();
$notifications = Auth::user()->notifications()->buyerNotifications()->get();
Auth::user() uses session data.
Try this:
optional(User::find(Auth::id())->notifications)->getBuyerNotifications;
or
$userId = 1; // Example id you can just pass the user Id.
User::find($userId)->notifications->getBuyerNotifications;
You can add two other methods in user model as follows
public function getBuyerNotifications() {
return $this->hasMany('App\Notification', 'buyer_id', 'id');
}
public function getSellerNotifications() {
return $this->hasMany('App\Notification', 'seller_id', 'id');
}
And you can call it directly from the user instance
$user->getBuyerNotifications();
$user->getSellerNotifications();

Laravel Tables Join

I have three tables:
notes: id, business_id, note
businesses: id, title, description
businessimages : id, business_id, image
I get my customers notes with this:
$customer = Auth::guard('customer-api')->user();
$notes = Note::where('customer_id', $customer->id)->with('business:id')-
>orderBy('id', 'desc')->get();
Now I want to get notes.id, businesses.id, businesses.title, businesses.description, businessimages.image for each notes and show all of them in one json array
How could I do?
Note::where('customer_id',$customer->id)
->join('businesses', 'businesses.id', '=', 'notes.buisness_id')
->join('businessimages', 'businesses.id', '=', 'businessimages.buisness_id')
->select(notes.id, businesses.id, businesses.title, businesses.description,businessimages.image)
->get();
Note model;
public function business() {
return $this->hasOne('App\Business', 'business_id', 'id');
}
Business mode;
public function businessImage()
{
return $this->hasOne('App\BusinessImage', 'business_id', 'id');
}
Your controller;
$notes = Note::where('customer_id', $customer->id)->with('business.businessImage')->orderBy('id', 'desc')->get();
You should consider using API Resources
This is a great way to organize a model(or a collection of models as well).
App\Note
use Illuminate\Database\Eloquent\Model;
class Note extends Model
{
public function business()
{
return $this->belongsTo('App\Business');
}
}
App\Business
namespace App;
use Illuminate\Database\Eloquent\Model;
class Business extends Model
{
public function note()
{
return $this->hasOne('App\Note');
}
public function businessImage()
{
return $this->hasOne('App\BusinessImage');
}
}
App\BusinessImage
namespace App;
use Illuminate\Database\Eloquent\Model;
class BusinessImage extends Model
{
protected $table = 'businessimages';
public function business()
{
return $this->belongsTo('App\Business');
}
}
App\Http\Resources\Note
namespace App\Http\Resources;
class Note
{
public function toArray($request)
{
return [
'noteId' => $this->resource->id,
'businessId' => $this->resource->business->id,
'businessTitle' => $this->resource->business->title,
'businessDescription' => $this->resource->business->description,
'businessImage' => $this->resource->business->businessImage->image
];
}
}
Somewhere in a controller
use App\Http\Resources\Note as NoteResource;
public function foo()
{
$customer = Auth::guard('customer-api')->user();
$notes = Note::where('customer_id', $customer->id)->with(['business','business.businessImage'])->orderBy('id', 'desc')->get();
return NoteResource::collection($notes);
}

Controller method issue in Laravel Eloquent

This is my Controller method wherein I want to fetch posts by user id.
I also have relationship defined in User model
public function posts()
{
return $this->hasMany('Post','user_id','id');
}
UserController.php
use App\Post;
public function findPostsByUser($id){
$user = User::findOrFail($id);
$posts = $user->posts()->get();
return $posts;
}
But it is giving me 'Post' not found error. Can someone help on this.
In your Post model make sure you have the relation defined like this:
public function user()
{
return $this->belongsTo('App\User');
}
And change your User model to this:
public function posts()
{
return $this->hasMany('App\Post','user_id','id');
}
Change relation method to
use App\Post;
....
public function posts()
{
return $this->hasMany(Post::class,'user_id','id');
}
or
public function posts()
{
return $this->hasMany('App\Post','user_id','id');
}
If you wont to get only posts that case use this
public function findPostsByUser($id){
$posts = Post::where('user_id', $id)->get();
return $posts;
}
The second solution has 1 query, but first solution has 2 query in db.
Also you can do it this way
public function findPostsByUser($id){
$posts = Post::whereUserId($id)->get();
return $posts;
}

Chain of hasMany or hasManyThrough through N models

How can I get all the submissions belongs to a particular user?
Trying this:
$user=User::find(1);
dd($user->submissions);
Throwing error:
Call to undefined method Illuminate\Database\Query\Builder::hasMany()
Will I have to loop through the models?
Here are the models:
class User extends Eloquent implements ConfideUserInterface, BillableInterface
{
public function categories()
{
return $this->hasMany('Category');
}
public function forms()
{
return $this->hasManyThrough('App\Models\Form', 'Category');
}
public function submissions()
{
return $this->hasMany('Category')->hasMany('Form')->hasMany('Submission');
}
}
class Category extends \Eloquent {
public function user()
{
return $this->belongsTo('User');
}
public function forms()
{
return $this->hasMany('App\Models\Form');
}
public function submissions()
{
return $this->hasManyThrough('Submission', 'App\Models\Form', 'id', 'form_id');
}
}
namespace App\Models;
class Form extends \Eloquent {
public function user()
{
return $this->category->user();
}
public function category()
{
return $this->belongsTo('Category');
}
public function submissions()
{
return $this->hasMany('Submission');
}
}
class Submission extends \Eloquent {
public function user()
{
return $this->form->category->user();
}
public function category()
{
return $this->form->category();
}
public function form()
{
return $this->belongsTo('App\Models\Form');
}
}
That doesn't really work that way with chaining relations...
What you can do, is this:
$submissions = Submission::whereHas('form.category.user', function($q){
$q->where('id', 1);
})->get();
Note that whereHas with nested relationships has only been added in the latest Laravel 4 release. Make sure to composer update.
If i'm not getting your question wrongly, you need to define relationship correctly.
According to laravel 4.2 you can use below kind of code to define relations:
class User extends \Eloquent implements ConfideUserInterface, BillableInterface{
//...
public function submissions(){
return $this->hasMany('Submission');
}
}
//...
class Submission extends \Eloquent {
public function user()
{
return $this->belongsTo('User');
}
//...
}
To further reading take a look at: http://laravel.com/docs/4.2/eloquent#relationships

Laravel: hasMany() with take() only working on first result

I have the following models.
class User extends Eloquent {
public function comments() {
return $this->hasMany('Comment');
}
}
class Comment extends Eloquent {
public function user() {
return $this->belongsTo('User');
}
}
For the sake of this example, a user could have 1,000s of comments. I am trying to limit them to just the first 10. I have tried doing it in the User model via
class User extends Eloquent {
public function comments() {
return $this->hasMany('Comment')->take(10);
}
}
and via UserController via closures
$users = User::where('post_id', $post_id)->with([
'comments' => function($q) {
$q->take(10);
}
]);
Both methods seem to only work on the first record of the result. Is there a better way to handle this?

Categories