Laravel eloquent relationship not accessing second table - php

I have 2 tables:
emails: email_id, name
email_templates: template_id, template_mid, template_lang, template_subject, template_mail
Template_mid is foreign key and associated with emails.id
My models:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class Email extends Model
{
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps = false;
/**
* Indicates primary key column.
*
* #var bool
*/
protected $primaryKey = "email_id";
public function template()
{
return $this->hasOne('App\Email_template', 'template_mid', 'email_id');
}
}
Email_template
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Email_template extends Model
{
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps = false;
/**
* Indicates primary key column.
*
* #var bool
*/
protected $primaryKey = "template_id";
}
When I run this in my controller:
public function index()
{
$emails = Email::all();
dd($emails);
}
I cannot access the the template method and I have only id, subject in the dumped results. How can I fix this?

Related models are not loaded automatically. You can either load them with with(), or individually:
Email::with('template')->get();
or
foreach($emails as $email)
{
dd($email->template);
}

Related

Trouble getting hasManyThrough to work in Laravel 9

In my Laravel project I'm having some trouble getting my hasManyThrough relationship to work, these are my models:
Pingtree
BuyerTier
PingtreeEntry
I want to get all of my BuyerTier models through my PingtreeEntry model.
This is my current relationship on my Pingtree model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Pingtree extends Model
{
use HasFactory, SoftDeletes;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'pingtrees';
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'is_enabled' => 'boolean',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'is_deleting',
];
/**
* Determine if we're editing the model
*
* #return bool
*/
public function getIsDeletingAttribute()
{
return false;
}
/**
* Get the company that owns the model.
*/
public function tiers()
{
return $this->hasManyThrough(
BuyerTier::class, // final model we want to access
PingtreeEntry::class, // intermediate model
'buyer_tier_id', // foreign key on intermediate model
'id', // foreign key on final model
'id', // local key
'pingtree_id' // local key on intermediate model
)->orderBy('processing_order', 'asc');
}
/**
* Get the pingtree entry model
*/
public function pingtree_entry()
{
return $this->belongsTo(PingtreeEntry::class, 'id', 'pingtree_id');
}
/**
* Get the company that owns the model.
*/
public function company()
{
return $this->belongsTo(Company::class);
}
/**
* Get the user that owns the model.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
And then I query this in my controller:
$pingtree = Pingtree::where('company_id', $company_id)
->where('id', $id)
->with([
'tiers.buyer',
'tiers.pingtree_entry'
])
->first();
This is what my pingtree_entries table looks like:
Right now, for some reason, despite having multiple tiers on my pingtree ID 3, I'm only ever getting 1 result back in my query, and I should be seeing all 4 tiers on my pingtree, what am I missing?

Extending model class causes Column not found error

I'm using https://github.com/spatie/laravel-permission
I have created a new class which extends the Role class. Here is the code for Role:
<?php
namespace Spatie\Permission\Models;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Traits\HasPermissions;
use Spatie\Permission\Exceptions\RoleDoesNotExist;
use Spatie\Permission\Contracts\Role as RoleContract;
use Spatie\Permission\Traits\RefreshesPermissionCache;
class Role extends Model implements RoleContract
{
use HasPermissions;
use RefreshesPermissionCache;
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
public $guarded = ['id'];
/**
* Create a new Eloquent model instance.
*
* #param array $attributes
*/
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->setTable(config('laravel-permission.table_names.roles'));
}
/**
* A role may be given various permissions.
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function permissions()
{
return $this->belongsToMany(
config('laravel-permission.models.permission'),
config('laravel-permission.table_names.role_has_permissions')
);
}
/**
* A role may be assigned to various users.
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users()
{
return $this->belongsToMany(
config('auth.model') ?: config('auth.providers.users.model'),
config('laravel-permission.table_names.user_has_roles')
);
}
/**
* Find a role by its name.
*
* #param string $name
*
* #throws RoleDoesNotExist
*
* #return Role
*/
public static function findByName($name)
{
$role = static::where('name', $name)->first();
if (! $role) {
throw new RoleDoesNotExist();
}
return $role;
}
/**
* Determine if the user may perform the given permission.
*
* #param string|Permission $permission
*
* #return bool
*/
public function hasPermissionTo($permission)
{
if (is_string($permission)) {
$permission = app(Permission::class)->findByName($permission);
}
return $this->permissions->contains('id', $permission->id);
}
}
My code was working fine when accessing this Role class directly for create()'s, but attempting to perform the same tasks using my new UserRole class, I am getting Column not found database errors when attempting to create a new Role.
Here is the UserRole class:
namespace App;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Permission\Models\Role;
class UserRole extends Role
{
use LogsActivity;
/**
* The attributes that should be logged.
*
* #var array
*/
protected static $logAttributes = ['name', 'permissions'];
}
So Role::create() works fine, but UserRole::create() does not.
Well changing the name to Role and then changing my use clause to as SpatieRole has fixed the issue. I'm guessing it was some type of class name relationship issue with Eloquent.
If you don't define the $table property on your Eloquent model, the table name is derived from the name of the Model. So, the Role model would use the roles table by default. The UserRole model would look for the user_roles table by default.
Since you still want to use the same table, but your model name is changed, you will need to define the $table property on your new model to make it look at the roles table.
class UserRole extends Role
{
protected $table = 'roles';
// ...
}

Laravel Eloquent Basic Query Issue

I am facing a problem with laravel eloquent, if some one can help me wtih this prolem, it will be very good.
I am trying to get data from database in laravel. According to document I tried use code below to get all rows in "menulist" table but I get an error which I couldn't understand since I am new at laravel.
App\Model\ConfigMenulist.php
namespace App\Model\Config;
use Illuminate\Database\Eloquent\Model;
class Menulist extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = "menulist";
/*
* Set increment column name
*
* #var string
*/
protected $primaryKey = "menuId";
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps = false;
// MASS ASSIGNMENT -------------------------------------------------------
// define which attributes are mass assignable (for security)
// we only want these 1 attributes able to be filled
protected $fillable = array('menuTitle');
}
AppController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Model\Config\Menulist;
class AppController extends Controller
{
public function index()
{
$menu = Menulist::all();
return view('app');
}
}
The error I got:
I solved the problem by editing DB_HOST=127.0.0.1 to DB_HOST=localhost. Thanks #rene-m for respond.

Not passing id into model in Laravel

I am using Eloquent's firstOrCreate() method to insert my data, or retrieve if it exists.
I need to get the $trip->id. If I echo it in the FlightController then it echo's the correct id, but it doesn't seem to pass it into the UserFlights Model to insert into the user_flights table.
I get this error on the page:
QueryException in Connection.php line 729: SQLSTATE[23000]: Integrity
constraint violation: 1048 Column 'user_trips_id' cannot be null (SQL:
insert into user_flights (airport_from, airport_to,
user_trips_id) values (1, 4, ))
Flow: User select's two airports (flying from and flying to) from the drop-down boxes (<select>) and adds them to their "trip". If they don't have a trip, it creates one, and then adds the two airports to their trip.
Schema
# `user_trips` table
Schema::create('user_trips', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->text('name');
});
# `user_flights ` table
Schema::create('user_flights', function (Blueprint $table) {
$table->increments('id');
$table->integer('trip_id')->unsigned();
$table->integer('airport_from')->unsigned();
$table->integer('airport_to')->unsigned();
$table->foreign('trip_id')->references('id')->on('user_trips')->onDelete('cascade');
});
FlightController
<?php
namespace App\Http\Controllers;
use App\UserFlights;
use App\UserTrips;
use Illuminate\Http\Request;
/**
* Class FlightController
*
* #package App\Http\Controllers
*/
class FlightController extends Controller
{
/**
* #param Request $request
* #param UserTrips $user_trips_obj
* #return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request, UserTrips $user_trips_obj)
{
// Retrieve the trip by the attributes, or create it if it doesn't exist...
$trip=$user_trips_obj->addTrip();
# Returns the ID correctly.
//echo $trip->id;exit;
$user_trips_obj->addFlight(
new UserFlights([
'airport_from'=>$request->flight_from,
'airport_to'=>$request->flight_to,
# Does not pass the `$trip->id` into the UserFlights model.
'user_trips_id'=>$trip->id
])
);
return back();
}
}
UserTrips Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class UserTrips
*
*/
class UserTrips extends Model
{
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps=FALSE;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable=[
'name',
'user_id'
];
/**
* #param UserFlights $user_flights_obj
* #return Model
*/
public function addFlight(UserFlights $user_flights_obj)
{
return $this->userflights()->save($user_flights_obj);
}
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function userflights()
{
return $this->hasMany('App\UserFlights');
}
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\User');
}
/**
* #return mixed
*/
public function addTrip()
{
// Retrieve the trip by the attributes, or create it if it doesn't exist...
$trip=$this->firstOrCreate([
'user_id'=>1,
'name'=>'My Trip'
]);
return $trip;
}
}
UserFlights Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* Class UserFlights
*
*/
class UserFlights extends Model
{
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps=FALSE;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable=[
'airport_from',
'airport_to',
'user_trips_id'
];
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function usertrips()
{
return $this->belongsTo('App\UserTrips');
}
}
Your addFlight() method calls $this->userflights()->save($user_flights_obj);.
When you call save() on the relationship object, it sets the foreign key on the object passed in ($user_flights_obj) to the id of the object that owns the relationship ($this). Then it saves the $user_flights_obj object.
Since your controller calls $user_trips_obj->addFlight(new UserFlights...), the $this reference inside your addFlight() method is referencing the $user_trips_obj instance from your controller. This instance is just an empty shell, with a blank id. Therefore, inside your addFlight() method, when you call save() on the relationship, it is going to set the foreign key on your new UserFlights instance to the id of the instance on which addFlight() was called (blank).
To solve this issue, you just need to call addFlight() on the $trip instance you created in the controller. That is the instance to which you want to relate the new UserFlights instance. Additionally, you don't need to set the foreign key manually; that is the whole reason for calling save() on the relationship.

Laravel 5 Auth change table columns

I changed some fields in users database table.
table name: users
primaryKey: user_id
username: user_username
password: user_password
e-mail: user_mail
in Illuminate\Foundation\AuthAuthenticatesUsers I added protected $username = 'user_username';
When I try login to my account, I see a blank page after I give my username and password. Debug is on but not working. What happened?
Auth::attempt(array(
'user_username' => 'pionas',
'user_password' => '12345',
));
In User model I added getAuthPassword and changed the column name to user_password. Log is clear.
Auth::loginUsingId(1); - not working
Probably all methods in Auth are not working.
My User model is:
<?php
namespace App\User;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
protected $primaryKey = 'user_id';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['user_username', 'user_mail', 'user_password', 'user_group_id', 'user_code', 'user_rang'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('user_password', 'remember_token');
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->user_password;
}
public function comment()
{
return $this->hasOne('UserField', 'user_id');
}
/**
You seem to have stripped some of the required traits that Laravel 5.1 uses. Here is an updated User model with those traits restored:
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
protected $primaryKey = 'user_id';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['user_username', 'user_mail', 'user_password', 'user_group_id', 'user_code', 'user_rang'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('user_password', 'remember_token');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken()
{
return $this->remember_token;
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
$this->remember_token = $value;
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->user_mail;
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->user_password;
}
public function comment()
{
return $this->hasOne('UserField', 'user_id');
}
/**
* Scope a query to only include users of a given type.
*
* #return \Illuminate\Database\Eloquent\Builder
*/
public function scopeOfStatus($query, $type)
{
return $query->where('user_status', $type);
}
}
You will need to do two things.
On your model, add the method getAuthPassword() (you already do that)
public function getAuthPassword()
{
return $this->user_password;
}
On your AuthController, when passing the $credentials to the $this->auth->validate() method (or the Auth::attemp() or anything else), you must set the array with a key to check for the password, and this key SHOULD be named as "password". All others keys can have any name, and you will use the name of your username column
$credentials['user_username'] = $request->input('user_username');
$credentials['password'] = $request->input('user_password');
Auth::attempt($credentials);

Categories