hasManyThough returns null - Eloquent - laravel

I'm looking to retrieve all transactions of an event which are created by a booking. I was thinking of using a hasManyThrough relationship. However it returns null. What am I doing wrong?
Event model:
public function booking(){
return $this->hasMany(Booking::class);
}
public function transaction(){
$this->hasManyThrough(Transaction::class, Booking::class);
}
Booking model:
public function event() {
return $this->belongsTo(Event::class);
}
public function user() {
return $this->belongsTo(User::class);
}
public function transaction(){
return $this->hasMany(Transaction::class);
}
Transaction model:
public function booking() {
return $this->belongsTo(Booking::class);
}
public function user() {
return $this->belongsTo(User::class);
}
My tables look like so

Related

accessing a parent of a parent relationship laravel

I am building an application in laravel in which each channel has some sections and you can post threads in the sections. I would like to access the channel from the thread.
The hierarchy so far is this
-channel
--section
---threads
here are the three model classes
channel
use Illuminate\Database\Eloquent\Model;
class Channel extends Model
{
public function users(){
return $this->belongsToMany('App\User');
}
public function posts(){
return $this->hasMany('App\Post');
}
public function isSubscribed($id){
return $this->users()->find($id);
}
public function sections(){
return $this->hasMany('App\Section');
}
}
section
{
public function channel(){
return $this->belongsTo('App\Channel');
}
public function threads(){
return $this->hasMany('App\Thread');
}
}
thread
{
protected $fillable=['title','body','solved'];
public function solutions(){
return $this->hasMany('App\Solution');
}
public function comments(){
return $this->hasMany('App\ThreadComment');
}
public function section(){
return $this->belongsTo('App\Section');
}
public function arguments(){
return $this->belongsToMany('App\Argument');
}
public function user(){
return $this->belongsTo('App\User');
}
public function reports(){
return $this->morphTo('App\Report','reportable');
}
}
what I would like to do is to have a channel() method in thread class that makes me access the channel without having to do $thread->section->channel each time
If you really want to, use an accesor.
public function getChannelAttribute()
{
return $this->section->channel;
}
If you don't have a problem using a package for this, use https://github.com/staudenmeir/eloquent-has-many-deep. You can have any levels of relationships.
Read the usage section of the package for details.

Relationship through one model

I have three tables - users, properties, devices.
users
id
name
properties
id
name
user_id
devices
id
name
property_id
How to define straight relationship to user model from devices model?
class Device extends Model
{
public function user()
{
return $this->....();
}
}
Is it possible to define such relation? Thanks.
Make sure to set all relation in other classes.
class Property extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
class Device extends Model
{
public function property()
{
return $this->belongsTo('App\Property');
}
public function user()
{
return $this->belongsTo('App\User', null, null, 'property');
}
}
You can provide a relation with in 4th parameter of belongsTo method.
//user model
public function role()
{
return $this->belongsTo('App\Role');
}
public function employee()
{
return $this->hasMany('App\Employee');
}
//role model
public function users()
{
return $this->hasMany('App\User');
}
//employee model
public function users()
{
return $this->belongsTo('App\User');
}
//value show using tinker command in command promote
App\User::find(1)->employee;
App\User::find(1)->role;
I think I have found the solution, this is what I end up with.
class Device extends Model
{
public function user()
{
$instance = new User();
$instance->setTable('properties');
$query = $instance->newQuery();
return (new BelongsTo($query, $this, 'property_id', $instance->getKeyName(), 'property'))
->join('users', 'users.id', '=', 'properties.user_id')
->select(DB::raw('users.*')
);
}
}
Hope this will be of help for somebody.

laravel relationship between 5 tables

I have 5 tables User, Profile, Address,State,City .Need to create relationship between tables.Address has State id , City id and Profile id in the table.Profile has User Id in the table.City has State Id in the table. How to write relationship between table
class City extends Model
{
public function state() {
return $this->belongsTo('App\State');
}
public function addresses() {
return $this->hasMany('App\Address');
}
}
class State extends Model
{
public function cities() {
return $this->hasMany('App\City');
}
public function addresses() {
return $this->hasMany('App\Address');
}
}
class Profile extends Model
{
public function address() {
return $this->belongsTo('App\Address');
}
public function user() {
return $this->belongsTo('App\User');
}
}
class Address extends Model
{
public function profile() {
return $this->belongsTo('App\Profile');
}
public function city() {
return $this->belongsTo('App\City');
}
public function state() {
return $this->belongsTo('App\State');
}
}
// users table
public function profile(){
return $this->hasOne('App\Profile');
}
Generally your model design is true, i have edited a few parts. Try the codes below.
class City extends Model
{
public function state()
{
return $this->belongsTo('App\State');
}
public function addresses()
{
return $this->hasMany('App\Address');
}
}
class State extends Model
{
public function cities()
{
return $this->hasMany('App\City');
}
public function addresses()
{
return $this->hasMany('App\Address');
}
}
class Profile extends Model
{
public function addresses()
{
return $this->hasMany('App\Address');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
class Address extends Model
{
public function profile()
{
return $this->belongsTo('App\Profile');
}
public function city()
{
return $this->belongsTo('App\City');
}
public function state()
{
return $this->belongsTo('App\State');
}
}
class User extends Model
{
public function profile()
{
return $this->hasOne('App\Profile');
}
}
By the way, Laravel relationships add default keys according to your method names. If you have problem about it you can find info from official documents. For example:
$this->belongsTo('App\Model', 'foreign_key', 'other_key');
as #mustafa.akcoban says...
When you use belongsTo Eloquent will work as follow
$this->belongsTo('App\City', 'foreign_key', 'other_key');
// foreign_key = is the primary key in the related model, by default 'id' for Eloquent
// other_key = is the field in the current model that contains the id of the other model, by default othermodelname_id for Eloquent
// For eg. 'App\City', 'id', 'city_id'
When you use hasMany Eloquent works as follow
$this->hasMany('App\Model', 'currentmodel_id', 'primary_key');
// currentmodel_id = is the field that contains the current model primary key in the related model
// primary_key = is the current primary key model that will be in the other model, by default id for Eloquent
// For eg. 'App\City', 'state_id', 'id'
Remember you can or can't use second and third parameter, if something is wrong Laravel dump will tell you what column was not found in the table, and you will can fix.
Please try and practice this, and let me know how it works :)

Laravel Polymorphic Relation not working

trying to get some polymorphic relations working in laravel 4.
I have a CoreUserAccount table that looks like so:
core_user_account:
id
profile_id
other columns
I then have 2 other tables core_user_client_profile and core_user_consultant_profile. They both have id fields.
i am trying to link them like so:
In the CoreUserAccount model:
public function profile()
{
return $this->morphTo();
}
And in both the other tables i have:
public function user()
{
return $this->morphOne('CoreUserAccount', 'profile');
}
But i don't seem to be able to get any of the profile data through the user object. Any ideas?
Cheers
EDIT
Here is my core_user_account table:
And here are my 2 different profile type tables core_user_client_profile and core_user_consultant_profile:
Here is my model for core_user_account:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class CoreUserAccount
extends Eloquent
implements UserInterface, RemindableInterface
{
protected $table = 'core_user_account';
protected $hidden = array('password');
protected $guarded = array('id', 'password');
public function profileType()
{
return $this->belongsTo('CoreUserProfileType');
}
public function address()
{
return $this->belongsTo('CoreUserAddress', 'user_account_id', 'id');
}
public function profile()
{
return $this->morphTo();
}
public function getAuthIdentifier() {
return $this->getKey();
}
public function getAuthPassword() {
return $this->password;
}
public function getReminderEmail() {
return $this->email;
}
public function getRememberToken() {
return $this->remember_token;
}
public function setRememberToken($value) {
$this->remember_token = $value;
}
public function getRememberTokenName() {
return 'remember_token';
}
}
And my core_user_client_profile model:
class CoreUserClientProfile
extends Eloquent
{
protected $table = 'core_user_client_profile';
public function profileLanguage()
{
return $this->belongsTo('CoreUserProfileLanguages');
}
public function user()
{
return $this->morphOne('CoreUserAccount', 'profile',null,'profile_id',null);
}
}
And my core_user_consultant_profile model:
class CoreUserConsultantProfile
extends Eloquent
{
protected $table = 'core_user_consultant_profile';
public function profileLanguage()
{
return $this->belongsTo('CoreUserProfileLanguages', 'consultant_profile_id', 'id');
}
public function qualifications()
{
return $this->belongsTo('CoreUserConsultantQualifications', 'profile_id', 'id');
}
public function registration()
{
return $this->belongsTo('CoreUserConsultantRegistrations', 'profile_id', 'id');
}
public function specialities()
{
return $this->belongsTo('CoreUserConsultantProfileSpeciality', 'profile_id', 'id');
}
public function user()
{
return $this->morphOne('CoreUserAccount', 'profile');
}
}
I have read the document pointed out in the comments below and understand i seem to have to have a type column in my DB. But what data needs to be stored here? does it automatically get stored or do i have to store it?
Cheers
You should have to have profile_type, and profile_id columns. In profile_type will be stored values: 'CoreUserConsultantProfile' or 'CoreUserClientProfile'. This fields will be populated automaticlly when you save data.
This is example how save data in polymorph relation.
$profile = CoreUserConsultantProfile::find(1);
$account = new CoreUserAccount();
$profile->profile()->save($account);
So now, profile_id=1, and profile_type = 'CoreUserConsultantProfile'

Laravel Relationship error trying to call a relationship within the model

On Laravel "4.1.x-dev",
How can I call a method on a relation within the model? From the below example
public function userLink() {
return $this->user->link;
}
My function userLink gives me the error : Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
Also is there another way for me to access the linked user from Drawing with some kind of eager loading trick?
I have several different type of users. Each type of user has it's own table with an ID in each table that corresponds to the *ID** of the users table. In my Users model I have a method called ''link'' that performs a ''morphTo'' and gets me the correct user object.
class Drawing extends Eloquent {
public function user() {
return $this->belongsTo('User', 'user_id');
}
// this throws the relation error above, also I beleive this does two queries, anyway to improve this?
public function userLink() {
return $this->user->link;
}
}
class User extends Eloquent {
public function link() {
return $this->morphTo('User', 'type', 'id');
}
}
class Retailer extends Eloquent {
public function user() {
return $this->belongsTo('User', 'id');
}
}
class Manufacturer extends Eloquent {
public function user() {
return $this->belongsTo('User', 'id');
}
}
Try this instead:
Drawing::first()->user->link;
or this:
// Drawing model
public function user()
{
return $this->belongsTo('User', 'user_id');
}
// Drawing model
// Requires above relation
public function userLink()
{
return $this->user->link;
}
Then:
$ulink = Drawing::first()->userLink();
Also check the Defining An Accessor.
Update: Just make changes to your method like this (Create an accessor):
public function getUserLinkAttribute()
{
return $this->user->link;
}

Resources