How to get the feeds of the user whom you are following. Right now I'm able to get the id of the user whom you are following but struggling to get the feeds of the following user. Followscontroller
<?php
namespace App\Http\Controllers;
use Redirect;
use App\User;
use Laracasts\Commander\CommanderTrait;
use App\FollowUserCommand;
use Sentinel;
use Illuminate\Support\Facades\Input;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class FollowsController extends Controller
{
use CommanderTrait;
/**
* Follow a User
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store()
{
$input = array_add(Input::all(), 'user_id', Sentinel::getuser()->id);
$this->execute(FollowUserCommand::class, $input);
return Redirect::back();
}
/**
* Unfollow a User
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
FollowUserCommand
<?php namespace App;
use App\User;
class FollowUserCommand {
public $user_id;
public $userIdToFollow;
function __construct($user_id, $userIdToFollow)
{
$this->user_id = $user_id;
$this->userIdToFollow = $userIdToFollow;
}
}
FollowUserCommandHandler
<?php namespace App;
use Laracasts\Commander\CommandHandler;
class FollowUserCommandHandler implements CommandHandler {
protected $userRepo;
function __construct(UserRepository $userRepo)
{
$this->userRepo = $userRepo;
}
public function handle($command)
{
$user = $this->userRepo->findById($command->user_id);
$this->userRepo->follow($command->userIdToFollow, $user);
return $user;
}
}
UserRepository
<?php namespace App;
use App\User;
class UserRepository {
public function save(User $user)
{
return $user->save();
}
public function getPaginated($howMany = 4)
{
return User::orderBy('first_name', 'asc')->paginate($howMany);
}
public function findByUsername($username)
{
return User::with(['feeds' => function($query)
{
$query->latest();
}
])->whereUsername($username)->first();
}
public function findById($id)
{
return User::findOrFail($id);
}
public function follow($userIdToFollow, User $user)
{
return $user->follows()->attach($userIdToFollow);
}
}
User.php
<?php namespace App;
use Cartalyst\Sentinel\Users\EloquentUser;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends EloquentUser {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes to be fillable from the model.
*
* A dirty hack to allow fields to be fillable by calling empty fillable array
*
* #var array
*/
protected $fillable = [];
protected $guarded = ['id'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* To allow soft deletes
*/
use SoftDeletes;
protected $dates = ['deleted_at'];
public function feeds()
{
return $this->hasMany('App\Feed');
}
public function comment()
{
return $this->hasMany('App\Comment');
}
// This function allows us to get a list of users following us
public function follows()
{
return $this->belongsToMany(self::class, 'follows', 'follower_id', 'followed_id')->withTimestamps();
}
// Get all users we are following
public function following()
{
return $this->belongsToMany('User', 'followers', 'user_id', 'follow_id')->withTimestamps();
}
}
It should be fairly straightforward.
$user = User::with('following.feeds')->get();
foreach ($user->following as $followedUser) {
foreach ($followedUser->feeds as $feed) {
}
}
using sub query I am able to get like below. if some one needs other way, check the following code
$posts = Post::whereIn('user_id', function($query) use($id)
{
$query->select('leader_id')
->from('followers')
->where('follower_id', $id);
})->orWhere('user_id', $id)->latest()->paginate(10);
Related
I have 2 types of user Athletes and Teams. I created 3 tables users,athletes & teams. I am storing username & password in users table and others information in athletes & teams table. I would like to display Athletes and Teams information in home page.
My User model is like below
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $guarded = [];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = ['password', 'remember_token',];
protected $fillable = ['email','password','remember_token','category_id'];
public function team()
{
return $this->hasOne(Team::class);
}
public function athlete()
{
return $this->hasOne(Athlete::class);
}
}
My Team model is like below
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
public $guarded = [];
protected $fillable = ['first_name','last_name','user_id','how_did_find','social_media',];
public function user()
{
return $this->belongsTo(User::class);
}
}
My Athlete model is like below
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Athlete extends Model
{
public $guarded = [];
protected $fillable = ['user_id','social_media','youtube_video','website'];
public function user()
{
return $this->belongsTo(User::class);
}
}
I am using below code in controller.
$staff_picks = User::orderBy('id','desc')->take(10)->with('athlete','team')->get();
This is how it should be
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $guarded = [];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = ['password', 'remember_token',];
protected $fillable = ['email','password','remember_token','category_id'];
public function team()
{
return $this->hasOne(Team::class);
}
public function athlete()
{
return $this->hasOne(Athlete::class);
}
}
class Team extends Model
{
public $guarded = [];
protected $fillable = ['first_name','last_name','user_id','how_did_find','social_media',];
public function user()
{
return $this->belongsTo(User::class);
}
}
class Athlete extends Model
{
public $guarded = [];
protected $fillable = ['user_id','social_media','youtube_video','website'];
public function user()
{
return $this->belongsTo(User::class);
}
}
And the query
$staff_picks = User::orderBy('id','desc')->take(10)->with('athlete','team')->get();
And the iteration
foreach($staff_picks as $r){
$r->teams->social_media; //(user can be either teams or athletes so must check for null)
$r->athletes->social_media; //(user can be either teams or athletes so must check for null)
}
In athlete & team model create a column called user_id and in user model create two methods as hasMany relation for athletes and teams models.
After login get the data as
User::where('id', 1)->with('teams', 'athletes')->first();
Relations inside User modal can be written as below.
teams() {
return $this->hasMany(Team::class);
}
athletes() {
return $this->hasMany(Athlete::class);
}
Background
Note: this is using Laravel 5.3, Please don't judge.
We are trying to use dependency injection with our laravel controllers and push as much business logic into repos that are injected to controllers upon the controller instantiation.
We already have this functioning example:
class AcmeController extends Controller
{
protected $repository;
public function __construct(AcmeInterface $repository)
{
$this->repository = $repository;
}
}
inside app/Providers/RepositoryServiceProvider.php we do the binding:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind(\App\Repositories\Contracts\AcmeInterface::class, \App\Repositories\OpCity\AcmeRepo::class);
}
}
and then the AcmeRepo naturally implements the AcmeInterface:
class AcmeRepo implements AcmeInterface
Question
right now we have a case where some of the data of the same model is persisted in a memory type storage (redis) and the rest is persisted in relational db storage (psql). We would like to have two separate repos where each repo is specific to its storage type, ie RedisAcmeRepo and SqlAcmeRepo
How is it possible to do this in the AcmeController constructor?
public function __construct(AcmeInterface $sqlRepo, AcmeInterface $redisRepo)
{
$this->sqlRepo = $sqlRepo;
$this->redisRepo = $redisRepo;
}
For example you may do this:
$this->app->bind(AcmeController::class, function ($app) {
return new AcmeController($app->make(sqlRepo::class), $app->make(redisRepo::class));
});
Or this:
$this->app->when(AcmeController::class)
->needs('$sqlRepo')
->give($app->make(sqlRepo::class));
$this->app->when(AcmeController::class)
->needs('$redisRepo')
->give($app->make(redisRepo::class));
based on the answers above I came up with this solution, that kind of uses the composite pattern as well (I changed the name of the repos from Acme to ShopperLogs):
<?php
interface ShopperLogInterface
{
public function getLogs($from, $to, $shopper);
}
class ShopperLogsController extends Controller
{
/**
* service
*
* #var \App\Repositories\Contracts\ShopperLogInterface
* #access protected
*/
protected $manager;
public function __construct(ShopperLogInterface $manager)
{
$this->manager = $manager;
}
}
class ShopperLogManager implements ShopperLogInterface
{
protected $sqlRepo;
protected $redisRepo;
public function __construct(ShopperLogInterface $sqlRepo, ShopperLogInterface $redisRepo)
{
$this->sqlRepo = $sqlRepo;
$this->redisRepo = $redisRepo;
}
public function getLogs($from, $to, $shopper)
{
$todayRange = //get the today part of from -- to
/**
* array of ShopperLogs
*/
$todaysLogs;
if ($todayRange) {
$this->redisRepo->getLogs($todayRange->start, $todayRange->finish, $shopper);
}
$legacyRange = //get the part of from -- to that excludes today's range
/**
* array of ShopperLogs
*/
$legacyLogs;
if ($legacyLogs) {
$this->sqlRepo->getLogs($todayRange->start, $todayRange->finish, $shopper);
}
return merge($todayRange, $legacyRange);
}
}
class ShopperLogsSqlRepo implements ShopperLogInterface
{
/**
* #var /Illuminate\Database\Eloquent\Model/ShopperLogs
*/
protected $model;
/**
* #param /Illuminate\Database\Eloquent\Model/ShopperLogs $model
*/
public function __construct(ShopperLogs $model)
{
$this->model = $model;
}
public function getLogs($from, $to, $shopper)
{
$this->model->whereLogs //do eloquent sql stuff here
}
}
class ShopperLogsRedisRepo implements ShopperLogInterface
{
/**
* #var \Redis\Model\Class
*/
protected $model;
/**
* #param \Redis\Model\Class $model
*/
public function __construct(ShopperLogs $model)
{
$this->model = $model;
}
public function getLogs($from, $to, $shopper)
{
$this->model->whereLogs //do redis stuff
}
}
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind(\App\Repositories\Contracts\ShopperLogInterface::class, \App\Managers\ShopperLogManager::class);
$this->app->bind(ShopperLogsController::class, function ($app) {
return new ShopperLogsController($app->make(ShopperLogManager::class));
});
$this->app->bind(\App\Repositories\Contracts\ShopperLogInterface::class, function() {
return new \App\Managers\ShopperLogManager(new \App\Repositories\ShopperLogsSqlRepo(new \App\ShopperLog), new \App\Repositories\ShopperLogsRedisRepo(new \App\ShopperLog));
});
}
}
I Was following Laracasts video for creating follow option but when I'm clicking on Follow button on members page it is showing the above error. This is my followcontroller
<?php
namespace App\Http\Controllers;
use App\User;
use Laracasts\Commander\CommanderTrait;
use App\FollowUserCommand;
use Sentinel;
use Illuminate\Support\Facades\Input;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class FollowsController extends Controller
{
use CommanderTrait;
/**
* Follow a User
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store()
{
$input = array_add(Input::all(), 'user_id', Sentinel::getuser()->id);
$this->execute(FollowUserCommand::class, $input);
return Redirect::back();
}
/**
* Unfollow a User
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
This is my FollowUserCommand
<?php namespace App\User;
class FollowUserCommand {
public $user_id;
public $userIdToFollow;
function __construct($user_id, $userIdToFollow)
{
$this->user_id = $user_id;
$this->userIdToFollow = $userIdToFollow;
}
}
FollowUserCommandHandler
<?php namespace App;
use Laracasts\Commander\CommandHandler;
class FollowUserCommandHandler implements CommandHandler {
protected $userRepo;
function __construct(UserRepository $userRepo)
{
$this->userRepo = $userRepo;
}
public function handle($command)
{
$user = $this->userRepo->findById($command->user_id);
$this->userRepo->follow($command->userIdToFollow, $user);
return $user;
}
}
UserRepository
class UserRepository {
public function save(User $user)
{
return $user->save();
}
public function getPaginated($howMany = 4)
{
return User::orderBy('first_name', 'asc')->paginate($howMany);
}
public function findByUsername($username)
{
return User::with(['feeds' => function($query)
{
$query->latest();
}
])->whereUsername($username)->first();
}
public function findById($id)
{
return User::findOrFail($id);
}
public function follow($userIdToFollow, User $user)
{
return $user->follows()->attach($userIdToFollow);
}
}
User.php
<?php namespace App;
use Cartalyst\Sentinel\Users\EloquentUser;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends EloquentUser {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes to be fillable from the model.
*
* A dirty hack to allow fields to be fillable by calling empty fillable array
*
* #var array
*/
protected $fillable = [];
protected $guarded = ['id'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* To allow soft deletes
*/
use SoftDeletes;
protected $dates = ['deleted_at'];
// This function allows us to get a list of users following us
public function follows()
{
return $this->belongsToMany(self::class, 'follows', 'follower_id', 'followed_id')->withTimestamps();
}
// Get all users we are following
public function following()
{
return $this->belongsToMany('User', 'followers', 'user_id', 'follow_id')->withTimestamps();
}
}
Can anyone tell me why it is showing error even after "use App\FollowUserCommand;" has been declared in namespace.
Your namespace when declaring the FollowUserCommand class is wrong, it should be:
<?php namespace App;
class FollowUserCommand {...
And right now you have <?php namespace App\User;.
I'm trying to display the user group name in a view using Auth::user()->user_group->name, but apparently that doesn't work as I keep getting Trying to get property of non-object.
The code goes as follow
User_Group.php Model
<?php
class User_Group extends Eloquent {
protected $table = 'user_groups';
public function users() {
return $this->hasMany('User');
}
}
User.php Model
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
public function user_group()
{
return $this->belongsTo('User_Group', 'user_groups_id');
}
public function getGravatarAttribute()
{
$hash = md5(strtolower(trim($this->attributes['email'])));
return "http://www.gravatar.com/avatar/$hash?s=100";
}
public function isAdmin()
{
return $this->user_groups_id == 1;
}
}
My profile.blade.php view
<small><p class="pull-right">{{ Auth::user()->user_group->name }}</p></small>
Doing the following will print the user group id reference though:
{{ Auth::user()->user_groups_id }}
Rename the method to group instead of user_group
I have this model
When I try to reach the author's informations, I have
"Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$id"
"
class PostSignal extends BaseModel {
protected $fillable = [];
public function send($data)
{
$data['userid'] = $this->author()->id;
}
public function author()
{
return $this->belongsTo('User', 'user_id');
}
}
My user model is classic:
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends BaseModel implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
protected $fillable = ['username', 'email', 'password', 'last_connection', 'gravatar'];
/**
* Generate gravatar image
*
* #param integer $size Size of the image
*
* #return string Image
*/
public function gravatar($size = 32)
{
$email = md5($this->email);
return "//www.gravatar.com/avatar/{$email}?s={$size}";
}
public function Posts()
{
return $this->hasMany('BlogPost');
}
public function Comments()
{
return $this->hasMany('BlogPostComment');
}
public function signal()
{
return $this->hasmany('PostSignal');
}
}