Laravel eloquent relationship not giving me what i want - php

im trying to figure out eloquent and having a hard time understand it, even tho ive tried to read up on it.
I have two tables: fs_festivals, and fs_bands.
fs_festivals: id, name
fs_bands: id, festival_id, name
So, one festival can have many bands, and one band belongs to a festival.
Band-model (Band.php)
class Band extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $fillable = array(
'festival_id','name','note','bandak', 'bandakinfo','created_by','updated_by'
);
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'fs_bands';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
public function festival() {
return $this->belongsTo('Festival');
}
}
Festival-model (Festival.php):
class Festival extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $fillable = array(
'name','year','info','slug', 'image','created_by','updated_by'
);
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'fs_festivals';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
public function bands() {
return $this->hasMany('Band');
}
}
In my controller:
public function festivalHome() {
$bands = Band::all();
return View::make('fis.festivalhome')->with('bands',$bands);
}
And in my view:
Bands:
#foreach($bands as $band)
{{ $band->name }}
#endforeach
This lists all bands in the fs_bands table. I only want to list those who are set with the festival_id of the current festival im working on (say festival_id='2'). How should i go about this?
Ive tried this (seeing what others have done),
#foreach($festival->$bands as $band)
But it gives me an error of
Undefined variable: festival
What am I doing wrong? Also I wonder, should I do something else instead of $bands = Band:all(); to list them by festival_id? That would be an option but something tells me that this should be done automatically with eloquent.

Controller:
public function festivalHome($id) {
//$bands = Band::all();
$festival = Festival::with('bands')->whereId($id)->first(); //it will load festival with all his bands
return View::make('fis.festivalhome')->with('festival',$festival);
// or you can filter bands
$bands = Band::whereHas('festival', function($query) use ($id){
$query->whereId($id);
})->get(); //there will be only bands which will be on the festival
}
And in your view:
#foreach($festival->bands as $band)
{{ $band->name }}
#endforeach
//or
#foreach($bands as $band)
{{ $band->name }}
#endforeach

Related

Laravel Relationships - access input from other table

I cant get this working. This should be easy, but I cant figure out how to access a users gamer tag from different table using relationships.
Here is my User.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'gamertag', 'slug', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
// A user has many messages (Chat)
public function chat () {
return $this->hasMany('App\Chat');
}
}
Here is my Chat.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Chat extends Model {
protected $table = "chat";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'message', 'user_id'
];
// A Chat (or message) belong to a user
public function user() {
return $this->belongsTo('App\User');
}
}
And this is how I;m retrieving the messages:
class HomeController extends Controller {
public function index () {
$messages = Chat::orderBy('created_at', 'desc')->get();
return view('layouts.index', compact('messages'));
}
}
Why Im I having trouble getting the gamer tag to display?
#foreach($messages as $message)
<a class="author">{{ $message->user->gamertag }}</a>
#endforeach
/***** Edit***/
This works:
{{ dd($message->user->gamertag) }}
// This does NOT
{{ $message->user->gamertag }}
Try to use eager loading:
$messages = Chat::orderBy('created_at', 'desc')->with('user')->get();
I figured it out! Everything was working here, its just in my chat table, I had inserted a message with no identified user, so user_id = 0, and it was throwing that error off. Silly mistake.

Laravel relationship 2 layers

I have my database (=model) structure like that:
game:
lot (typeof Lot)
places (array type of Place)
place_id // just a number of a lot in some game
user_id
What should I do to call in everywhere like this:
User::find(1)->games() // returns Game collection where user has places
?
Models are:
class Place extends Model
{
protected $fillable = ['place_id', 'user_id', 'game_id'];
public function user() {
return $this->belongsTo(User::class);
}
public function game() {
return $this->belongsTo(Game::class);
}
}
User:
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name', 'email', 'steam_id', 'avatar'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['remember_token'];
/**
* Get all of the tasks for the user.
*/
public function items()
{
return $this->hasMany(SteamItem::class);
}
public function places() {
return $this->hasMany(Place::class);
}
}
The Game:
class Game extends Model
{
protected $fillable = ['lot_id'];
public function lot() {
return $this->belongsTo(Lot::class);
}
public function places() {
return $this->hasMany(Place::class);
}
}
Now I use this code in my User class:
public function games() {
return Game::with(['places' => function ($query) {
$query->where('user_id', $this->id);
}]);;
}
It doesn't work, because I need to make it as a relationship method, but with method returns a query builder.
In the finals I must call $user->games and it should return me all the games user linked to through place.
Okay. I think I understand now.
User has many Place. Place belongs to User.
Place belongs to Game. Game has many Place.
You can try this:
$user = User::with('places.game.lot')->find(1);
This will fetch the User and eager load all the relationships. Because Place belongsTo a Game, which in turn belongs to Lot, you can then do this:
#foreach ($user->places as $place)
<img src="{{$place->game->lot->imageUrl}}" />
#endforeach
Also, place is actually a pivot table, and you can take advantage of Eloquent's many-to-many relationship, which I would recommend reading about.

How to make HasMany Relation ship in Laravel 4.2

I have a user model looks like this
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 answer(){
return $this->hasMany('Answer','user_id');
}
public function supplierranking(){
return $this->hasMany('Supplierrank','userid','id');
}
}
Now each user will rank a company in a ranking Model which looks like this
Class Supplierrank extends Eloquent{
public function supplier(){
return $this->belongsTo('Supplier','supplierid','id');
}
public function user(){
return $this->belongsTo('User','userid','id');
}
}
I am able to get the user with the ranking details but I also have to get the details of companies that has been ranked from a Supplier table
which looks like this
Class Supplier extends Eloquent{
public function supplierranks(){
return $this->hasMany('Supplierrank','supplierid');
}
}
My query that I have done looks like this
$usersandranking = User::where('event','=',$exceleve)->with('supplierranking')->orderBy('id')->get();
It gets me user detail and there rankings but not the supplier names
Can any one help me on this

Make a variable with array of data from Laravel ManyToMany relationship

Im struggling to understand Laravels relationship usage. I finally managed to save the relationships between person and festival, using the model and this code:
$person = new Person;
$person->firstname = $firstname;
$person->lastname = $lastname;
$person->save();
$person_id = $person->id;
$person->festival()->attach($festival_id);
But I am not sure how to make a variable with all the persons of the festival im current working on. I store the value of festival_id in session:
$festival_id = Session::get('festival');
That is writing fine to my personFestival database.
id festival_id person_id
0 1 1
1 1 2
But i dont have any code in my PersonFestival-model, should I?
How can I retrieve all the persons of the festival with id=1 in a variable that I can use blade's foreach in a view on? Sorry about this mess, this is so confusing for me but i feel that im close to achieving it.
Tables:
persons (id, firstname, lastname)
festivals (id,name)
personFestival (id, person_id, festival_id)
Models:
class Festival extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $fillable = array(
'name','year','info','slug', 'image','created_by','updated_by'
);
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'fs_festivals';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
public function bands() {
return $this->hasMany('Band');
}
public function persons() {
return $this->belongsToMany('Person','fs_festival_persons','person_id','festival_id');
}
}
class Person extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $fillable = array(
'email','firstname','lastname','homepage', 'info','tlf','isonline','isbanned','username','password','password_temp','remember_token','code','active','created_by','updated_by'
);
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'fs_persons';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
public function festival() {
return $this->belongsToMany('PersonFestival','fs_festival_persons','person_id', 'festival_id');
}
}
class PersonFestival extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $fillable = array(
'person_id','festival_id'
);
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'fs_festival_persons';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
}
Pivot tables (your fs_festival_persons table) don't usually have a model associated with them, unless you really need some special logic for them. In this case, it doesn't look like you do, so you can probably just get rid of that model.
To answer your other question, all of the persons associated with a festival can be accessed through the relationship on your festival model:
$festival = Festival::find(1);
// Collection of Person objects via lazy loading
$persons = $festival->persons;
// Relationship object:
$relation = $festival->persons();
// Manually getting the Persons through the relationship:
$persons = $festival->persons()->get();
// You can iterate the Collection just like an array:
foreach ($persons as $person) {
var_export($person->name);
}
You can read more on querying relationships here: Laravel 4.2 / Laravel 5.0

Laravel: Trying to get relationship

User:
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 email_preferences()
{
return $this->hasOne('EmailPreference');
}
}
EmailPreference:
class EmailPreference extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'email_preferences';
public function user()
{
return $this->belongsTo('User');
}
}
users table
id PK
first_name
last_name
email
email_preferences table
id PK
user_id FK (users.id)
newsletter
I'm trying to display the email preferences for a user:
$user = Auth::user();
echo '<pre>';
print_r($user->email_preferences);
exit;
I get nothing...
It sounds like you want something like this:
<?php
$user = Auth::user();
echo 'Receive newsletter? ' . ($user->emailPreferences->newsletter ? 'Yes' : 'No');
EDIT:
I did some digging & found that underscores can be tricky when used in Eloquent function/property names. If you eliminate the underscore, things should just work:
<?php
class User extends Eloquent implements UserInterface, RemindableInterface {
public function emailPreferences()
{
return $this->hasOne('EmailPreference');
}
}
See this answer: Laravel 4 Eloquent ORM accessing one-to-one relationship through dynamic properties

Categories