I have in model Report following
public function reportedItem()
{
return $this->belongsTo('App\Item', 'item_id', 'id');
}
In Item model
public function report()
{
return $this->hasMany('App\Report', 'item_id','id');
}
In controller
public function details( $item_id )
{
$flags = Item::find($item_id)->report->unique('user_id');
return view('flags.details', compact('flags'));
}
Why when I do {{ dd(collect($flags)) }} in my view.blade I don't see anything from items table even when I query it Item::find($item_id)?
dd output
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Report extends Model
{
protected $table = 'reports';
protected $primaryKey = 'report_id';
protected $fillable = [
'item_id', 'report_body', 'user_id', 'report_reason'
];
public function reportedItem()
{
return $this->belongsTo('App\Item', 'item_id', 'id');
}
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id');
}
}
One way is to use something like this in your controller
public function details( $item_id )
{
$flags = Report::with('reportedItem')->where('item_id', '$item_id')->get();
try this
$flags = Item::find($item_id)->with('report')->get()
The below should work
$flags = Item::with('reportedItem')->find($item_id);
Then when you dd($flags) this look for the "relations" tab and inside that you'll see the info.
Related
So, yesterday I asked this question : How to get reports only by id of user?
So, I need to get reports from table reports with user_id which is logged.
My model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Reports extends Model
{
protected $table = 'reports';
// public $timestamps = false;
protected $fillable = [
'user_id', 'username', 'user_id_posted', 'username_posted', 'news_id','opinion_id','event_id','career_solution_id', 'subject', 'why_reporting','why_reporting_message','additional_message','private'
];
public function career_solutionReport()
{
return $this->belongsTo('App\CareerSolution','career_solution_id','id');
}
public function eventReport()
{
return $this->belongsTo('App\Event','event_id','id');
}
public function newsReport()
{
return $this->belongsTo('App\News','news_id','id');
}
public function opinionReport()
{
return $this->belongsTo('App\Opinion','opinion_id','id');
}
public function user()
{
return $this->belongsTo('App\User','user_id','id');
}
}
I'm using this line :
$reports = \App\Reports::where('user_id', Sentinel::getUser()->id)->get();
but at dd($reports);
I'm getting a few wrong values:
so, here user_id should be only 548, which is my user_id. But also I'm getting reports from user_id 542, which isn't correctly.
I guess you have your relationship setup in your Sentinel model:
public function reports()
{
return $this->hasMany(Report::class, 'user_id', 'id');
}
Then you can do this instead:
$reports = Sentinel::getUser()->reports;
I am a beginner in Laravel and am stuck with sending the data from pivot table to view. I have two models one is "Supplier" and another is "Product" which I have created as follows:
Supplier.php
class Supplier extends Model
{
protected $keyType = 'string';
public $incrementing = false;
public function products()
{
return $this->belongsToMany(
'App\Product',
'inward_stock',
'supplier_id',
'product_id'
)->withPivot(
'product_dimension',
'quantity',
'expiry_date',
'type',
'QR_code',
'sales_price',
'arrival_date',
'occassion',
'discount_percentage',
'payment_date',
'cost',
'paid_status',
'sku'
)->withTimestamps();
}
}
Product.php
class Product extends Model
{
protected $keyType = 'string';
protected $primaryKey = 'product_id';
public $incrementing = false;
public function suppliers()
{
return $this->belongsToMany('App\Supplier');
}
}
Now I want to access all the data from the pivot table named as "inward_stock" from my controller and want to send it to the view named "inward-stock-list", I have created "inwardstockController" for that purpose and want to know how to send it to the view using that controller.
I think the most effective way is to create model for pivot table:
class InwardStock extends Model
{
protected $table = 'inward_stock';
public function supplier()
{
return $this->belongsTo('App\Supplier', 'supplier_id', 'supplier_id');
}
public function product()
{
return $this->belongsTo('App\Product', 'product_id', 'product_id');
}
}
inwardstockController:
$inwardStocks = InwartStock::with(['product', 'supplier'])->get();
View:
#foreach($inwardStocks as $inwardStock)
{{ $inwardStock->supplier->id }}
{{ $inwardStock->product->id }}
#endforeach
I'm getting the following error whenever i go on to a users page, its supposed to show if the authenticated user is already following the user that the profile is on.
Could this be a problem with the relationship setup, it hasMany
Stack trace
local.ERROR: Call to a member function addEagerConstraints() on
boolean {"userId":1,"email":"fakeemail#aol.com","exception":"[object]
(Symfony\Component\Debug\Exception\FatalThrowableError(code: 0):
Call to a member function addEagerConstraints() on boolean at
/Applications/MAMP/htdocs/elipost/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:522)"}
[]
UserController.php
public function getProfile($user)
{
$users = User::with([
'posts.likes' => function($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
},
'follow',
'follow.follower'
])->with(['followers' => function($query) {
$query->with('follow.followedByMe');
$query->where('user_id', auth()->user()->id);
}])->where('name','=', $user)->get();
$user = $users->map(function(User $myuser){
return ['followedByMe' => $myuser->followers->count() == 0];
});
if (!$user) {
return redirect('404');
}
return view ('profile')->with('user', $user);
}
MyFollow(model)
<?php
class MyFollow extends Model
{
use SoftDeletes, CanFollow, CanBeFollowed;
protected $fillable = [
'user_id',
'followable_id'
];
public $timestamps = false;
protected $table = 'followables';
public function follower()
{
return $this->belongsTo('App\User', 'followable_id');
}
public function followedByMe()
{
return $this->follower->getKey() === auth()->id();
}
}
MyFollow
use Overtrue\LaravelFollow\Traits\CanFollow;
use Overtrue\LaravelFollow\Traits\CanBeFollowed;
class MyFollow extends Model
{
use SoftDeletes, CanFollow, CanBeFollowed;
protected $fillable = [
'user_id',
'followable_id'
];
public $timestamps = false;
protected $table = 'followables';
public function follower()
{
return $this->belongsTo('App\User', 'followable_id');
}
public function followedByMe()
{
return $this->follower->getKey() === auth()->id();
}
}
Post
class Post extends Authenticatable
{
protected $fillable = [
'title',
'body',
'user_id',
'created_at',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany('App\Comment');
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function likedByMe()
{
foreach($this->likes as $like) {
if ($like->user_id == auth()->id()){
return true;
}
}
return false;
}
}
Likes
<?php
namespace App;
use App\Post;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Like extends Model
{
use SoftDeletes;
protected $fillable = [
'user_id',
'post_id'
];
}
User(model)
class User extends Authenticatable
{
use Notifiable,CanFollow, CanBeFollowed;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function posts()
{
return $this->hasMany(Post::class);
}
public function images()
{
return $this->hasMany(GalleryImage::class, 'user_id');
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function follow()
{
return $this->hasMany('App\MyFollow');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
}
As Jonas Staudenmeir stated, followedByMe isn't a relationship, it's a regular function and what it does is returning a boolean. I'm confused at why you've got a follow on your user model and trying to get information from the follow's follower? Just simplify, I see too much unneeded eager loading here.
Searching by indexed elements (id) > searching by name, any day of the week
Edit:
UserController
public function getProfile(Request $request, $id)
{
//$request->user() will get you the authenticated user
$user = User::with(['posts.likes','followers','follows','followers.follows'])
->findOrFail($request->user()->id);
//This returns the authenticated user's information posts, likes, followers, follows and who follows the followers
//If you wish to get someone else's information, you just switch
//the $request->user()->id to the $id if you're working with id's, if you're
//working with names, you need to replace findOrFail($id) with ->where('name',$name')->get() and this will give you
//a collection, not a single user as the findOrFail. You will need to add a ->first() to get the first user it finds in the collection it results of
//If you're planning on getting an attribute (is_following = true) to know if
//the authenticated user is following, you can use an accessor in the User model and write this after you've fetched the instance of the User
//$user->append('is_following');
return view ('profile')->with('user', $user);
}
User Model
//Accessor
//People who this user follows
public function getIsFollowingAttribute()
{
return MyFollow::where('followable_id',$this->attributes['id'])->where('user_id',Auth()->user()->id)->count() > 0 ? true : false;
}
//Relationships
//People who this user follows
public function follow()
{
return $this->hasMany('App\MyFollow','user_id','id');
}
//People who follows this user
public function followers()
{
return $this->hasMany('App\MyFollow','followable_id','id');
}
//Posts of this user
public function posts()
{
return $this->hasMany('App\Post','user_id','id');
}
//Likes of this user, not sure about this one tho, we're not using this for now but it could come in handy for you in the future
public function likes()
{
return $this->hasManyThrough('App\Likes','App\Post','user_id','user_id','id');
}
Post Model
//Who like this post
public function likes()
{
return $this->hasMany('App\Post','user_id','id');
}
MyFollow Model
//Relationships
//People who follow this user
public function followers()
{
return $this->hasMany('App\MyFollow','followable_id','user_id');
}
//Relationships
//People who this user follows
public function follow()
{
return $this->hasMany('App\MyFollow','user_id','followable_id');
}
With the help of #abr i found a simple fix, simple solution.
MyFollow.php(model)
public function followers()
{
return $this->hasMany('App\MyFollow','followable_id','user_id');
}
//Relationships
//People who this user follows
public function follow()
{
return $this->hasMany('App\MyFollow','user_id','followable_id');
}
User.php(model)
public function getIsFollowingAttribute()
{
return MyFollow::where('followable_id',$this->attributes['id'])->where('user_id',Auth()->user()->id)->count() > 0 ? true : false;
}
public function follow()
{
return $this->hasMany('App\MyFollow');
}
UserController.php
public function getProfile($user)
{
$users = User::with(['posts.likes' => function($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
}, 'followers','follow.followers'])
->with(['followers' => function($query) {
}])->where('name','=', $user)->get();
$user = $users->map(function(User $myuser){
$myuser['followedByMe'] = $myuser->getIsFollowingAttribute();
return $myuser;
});
if(!$user){
return redirect('404');
}
return view ('profile')->with('user', $user);
}
it works now. :)
I have two tables, one called "products" and another "product_brands".
A product has one brand, and a brand can belong to many products.
I have:
class Product extends Eloquent {
protected $table = 'products';
public function type() {
return $this->hasOne('ProductTypes');
}
public function brand()
{
return $this->hasOne('ProductBrands', 'id', 'brand_id');
}
public function image() {
return $this->hasMany('ProductImages');
}
public function toArray() {
$ar = $this->attributes;
$ar['type'] = $this->type;
$ar['brand'] = $this->brand;
return $ar;
}
public function getBrandAttribute() {
$brand = $this->brand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
}
And my controller:
class ProductsController extends BaseController {
public function index($type_id) {
$Product = new Product;
$products = $Product->where('type_id', $type_id)->get();
return View::make('products.products', array('products' => $products));
}
}
Ideally I would like the column from "product_brands" to be in the same array as the columns from "products", hence why I am trying that stuff with toArray() and getBrandAttribute() but it isn't working.
How can I do this?
I'm sure the getBrandAttribute accessor collides with the brand relationship. Try this instead:
class Product extends Eloquent {
protected $table = 'products';
public function type() {
return $this->hasOne('ProductTypes');
}
public function productBrand() {
return $this->hasOne('ProductBrands', 'id', 'brand_id');
}
public function image() {
return $this->hasMany('ProductImages');
}
public function getBrandAttribute() {
$brand = $this->productBrand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
protected $appends = array('brand'); // this makes Laravel include the property in toArray
}
You should change your accessor to other name:
public function getSpecBrandAttribute() {
$brand = $this->brand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
and in toArray you should then use:
public function toArray() {
$ar = $this->attributes;
$ar['type'] = $this->type;
$ar['brand'] = $this->spec_brand;
return $ar;
}
That's because you shouldn't create fields with the same name as relationship name.
In addition as it's one to many relationship, probably for brand() you should use belongsTo and not hasOne
I figures this works for automatically fetching user and replies when I am serializing my object to JSON, but is overriding toArray really the proper way of doing this?
<?php
class Post extends Eloquent
{
protected $table = 'posts';
protected $fillable = array('parent_post_id', 'user_id', 'subject', 'body');
public function user()
{
return $this->belongsTo('User');
}
public function replies()
{
return $this->hasMany('Post', 'parent_post_id', 'id');
}
public function toArray()
{
$this->load('user', 'replies');
return parent::toArray();
}
}
Instead of overriding toArray() to load user and replies, use $with.
Here's an example:
<?php
class Post extends Eloquent
{
protected $table = 'posts';
protected $fillable = array('parent_post_id', 'user_id', 'subject', 'body');
protected $with = array('user', 'replies');
public function user()
{
return $this->belongsTo('User');
}
public function replies()
{
return $this->hasMany('Post', 'parent_post_id', 'id');
}
}
Also, you should be using toArray() in your controllers, not your models, like so:
Post::find($id)->toArray();
Hope this helps!
I must submit a new answer since I'm a SO pleb. A more proper way to accomplish this for those finding this on Google like I did would be to avoid using protected $with if you don't have to and instead move that with() call to your retrieval.
<?php
class Post extends Eloquent
{
protected $table = 'posts';
protected $fillable = array('parent_post_id', 'user_id', 'subject', 'body');
public function user()
{
return $this->belongsTo('User');
}
public function replies()
{
return $this->hasMany('Post', 'parent_post_id', 'id');
}
}
And then you could modify the Post call to pre-load as needed:
Post::with('user','replies')->find($id)->toArray();
This way, you won't be including un-needed data every time you grab a record, if you don't need it.