I have three tables, they are :
Contacts
contact_name
contact_email
contact_phone
Locations
location_name
location_country
Association Contacts
association_contact_id
association_contacts_id
contacts_type
In my models, I've set the Polymorphs...
AssociationContact
public function contact()
{
return $this->morphTo();
}
Client
public function contact()
{
return $this->morphToMany(
// the related model
'App\Models\AssociationContact',
// the relationship name
'contact',
// the table name, which would otherwise be derived from the relationship name - twowordables
'association_contacts',
// the foreign key will be twowordable_id, derived from the relationship name, which you're adhering to
'association_contact_id',
// the 'other' key, which would otherwise be derived from the related model's snake case name - two_word_id
'association_contacts_id'
);
}
When running the following code :
$clients = Client::all();
foreach($clients as $client)
{
echo "<pre>";
print_r($client->contact);
echo "</pre>";
}
I get the following error :
Syntax error or access violation: 1066 Not unique table/alias: 'association_contacts' (SQL: select `association_contacts`.*, `association_contacts`.`association_contact_id` as `pivot_association_contact_id`, `association_contacts`.`association_contacts_id` as `pivot_association_contacts_id`, `association_contacts`.`contact_type` as `pivot_contact_type` from `association_contacts` inner join `association_contacts` on `association_contacts`.`id` = `association_contacts`.`association_contacts_id` where `association_contacts`.`association_contact_id` = 7 and `association_contacts`.`contact_type` = App\Models\Client)
It must be how I've set up the model relations, But not sure what I've done wrong.
Cheers
Put this in AssociationContact:
public function contact()
{
return $this->morphTo(null,'contacts_type','association_contacts_id');
}
Change the relationship in your Client table to this:
public function contact()
{
return $this->morphMany('App\Models\Contact','contact','contacts_type','association_contacts_id');
}
This should work.
Related
I have a many-to-many database relationship set up in an existing Laravel installation between users and agencies.
On the frontend I'm using a drop down filter to send an agency_id to the server that is supposed to filter/return all the users by this agency_id variable.
In my models:
User.php
/**
* The agencies that belong to the user.
*/
public function agencies()
{
return $this->belongsToMany('App\Agency');
}
Agency.php
/**
* The users that belong to the agency.
*/
public function users()
{
return $this->belongsToMany('App\User');
}
When I query the database, I check if the agency parameter is present in the header
->when($request->agency, function ($q) use ($request, $schema) {
// Determine whether agency_id foreign key exists or if it's a pivot relationship
if(Schema::hasColumn($schema, 'agency_id'))
{
return $this
->repository
->whereAgency($q, \Hashids::decode($request->agency)[0]);
}
else
{
return $this
->repository
->whereAgencyPivot($q, \Hashids::decode($request->agency)[0]);
}
})
In the repository I do the following:
public function whereAgencyPivot($q, string $agency)
{
return $q->wherePivot('agency_id', $agency);
}
This returns the following error:
Column not found: 1054 Unknown column 'pivot' in 'where clause'
I have also tried:
public function whereAgencyPivot($q, string $agency)
{
return $q->agencies()->where('agency_user.agency_id', $agency);
}
which returns:
Call to undefined method Illuminate\Database\Eloquent\Builder::agencies()
Is there anything I'm missing?
So you want to get all the users against a pre selected agency which is linked with users in many-many relationship. Please correct me if I have miss understood.
To get many to many relationship
Agency::with('users')->where('id', 1)->get(); // id is injected dynamically.
To conditionally load relationship
if(some condition) {
$agency->load('users'); // It'll fetch all users against the given agency.
}
To get only users information
$data = Agency::with('users')->where('id', 1)->first();
$data->users; // gives you only users collection
The answer ended up being:
return $q->whereHas('agencies', function($query) use ($agency) {
$query->where('id', $agency);
});
I have 4 tables:
Table name: clients
Fields: id, name, slug
Table name: projects
Fields: id, slug
Table name: project_translation
Fields: id, locale, project_id, title
Table name: client_project
Fields: id, client_id, project_id
Relationships
In the Project model
public function clients()
{
return $this->belongsToMany(Client::class,'client_project')->withTimestamps();
//return $this->belongsToMany('Client')->withTimestamps()->orderBy('priority', 'desc');
}
In the Client model
public function projects()
{
return $this->belongsToMany(Project::class,'client_project')->withTimestamps();
}
public function translate()
{
return $this->belongsToMany(ProjectTranslation::class,'project_translations')->withTimestamps();
}
In Client_Project model
public function clients()
{
return $this->hasMany('App\Models\Project');
}
public function projects()
{
return $this->hasOne('App\Models\Client');
}
In ProjectTranslation model
public function client()
{
return $this->hasMany('App\Models\Client');
}
And I'm trying to access data in controller like this:
$client_project = Client::find($id)->translate;
return $client_project;
This give me the next error:
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique
table/alias: 'project_translations' (SQL: select
`project_translations`.*, `project_translations`.`client_id` as
`pivot_client_id`, `project_translations`.`project_translation_id` as
`pivot_project_translation_id`, `project_translations`.`created_at` as
`pivot_created_at`, `project_translations`.`updated_at` as
`pivot_updated_at` from `project_translations` inner join
`project_translations` on `project_translations`.`id` =
`project_translations`.`project_translation_id` where `project_translations`.`client_id` = 22)
I'm not sure, but I think something is wrong with Relationships.
I'm in Client blade, and I want to show the projectstranslations of the projects of this client.
Here I formatted you query so it's readable, as I said in the comments I am not a laravel user. But I know Sql
select
`project_translations`.*,
`project_translations`.`client_id` as `pivot_client_id`,
`project_translations`.`project_translation_id` as `pivot_project_translation_id`,
`project_translations`.`created_at` as `pivot_created_at`,
`project_translations`.`updated_at` as `pivot_updated_at`
from
`project_translations` <-- Duplicate Table with no alias
inner join
`project_translations` on `project_translations`.`id` = `project_translations`.`project_translation_id`
where
`project_translations`.`client_id` = 22
you don't need Client_Project model.
In the Project model
public function clients()
{
return $this->belongsToMany(Client::class,'client_project')->withTimestamps();
}
public function translates()
{
return $this->hasMany(ProjectTranslation::class);
}
In the Client model :
public function projects()
{
return $this->belongsToMany(Project::class,'client_project')->withTimestamps();
}
In the ProjectTranslation model :
public function project()
{
return $this->belongsTo('App\Models\Project');
}
In the controller :
$client_projects = Client::find($id)->projects; //all client projects
return $client_projects;
In the view after geting this $client_projects and looping over it you can get the translations of a project by :
$client_project->translates // for single projects you will get its translates :)
For Project you have many to many with clients and it has one to many translates => in the documentation links there are many examples :)
I'm trying to eager load nested relationships, but I'm having trouble returning the correct results.
Here are the models:
User.php
class User extends Model
{
public function universities()
{
return $this->hasMany('\StudentApp\Models\UserUniversity');
}
}
UserUniversity.php
class UserUniversity extends Model
{
protected $fillable = [ 'user_id', 'university_id', 'choice' ];
public function university()
{
return $this->hasOne('\StudentApp\Models\University');
}
}
University.php
class University extends Model
{
protected $table = 'university';
}
What I want to do is get a user by ID, fetch the users universities from the UserUniversity pivot table, and then fetch the name of that university from the University table.
I've tried the following to test if it works:
$user = User::with('universities')->find($this->jwtObject->uid);
return $response->withJson($user->universities[0]->university);
But I get the following error:
Column not found: 1054 Unknown column 'university.user_university_id' in 'where clause' (SQL: select * from `university` where `university`.`user_university_id` = 10 and `university`.`user_university_id` is not null limit 1) [] {"uid":"28c5a97"}
user.user_university_id is incorrect. That column doesn't exist and I'm not sure why it's trying to use that column.
What it should be using is user.university_id
How can I do this?
You should add foreign key and primary key in relation:
public function universities()
{
return $this->hasMany('\StudentApp\Models\University', 'university_id', 'id');
}
Correct nested eager loading syntax is:
User::with('universities.university')
Also, make sure you've using the correct foreign key in the university table:
user_university_id
Or define another key in the relationship:
public function university()
{
return $this->hasOne('\StudentApp\Models\University', 'another_foreign_key');
}
I have the following schema set up:
users:
id
departments:
id
department_user:
id
department_id
user_id
I also have the following relationships set up:
User Model
public function departments()
{
return $this->belongsToMany('App\Resources\Eloquent\Models\Department', 'department_users');
}
Department Model
public function users()
{
return $this->belongsToMany(User::class, 'department_users');
}
For some reason, when I am trying to access through the user model $user->departments, it doesn't work - but $department->users does.
Outputting the eloquent query is as follows:
select `departments`.*, `department_users`.`user_id` as `pivot_user_id`, `department_users`.`department_id` as `pivot_department_id` from `departments` inner join `department_users` on `departments`.`id` = `department_users`.`department_id` where `department_users`.`user_id` is null
I can't seem to figure out why it is looking to see if department_users.user_id is null, when it should be looking for the user's id.
Any ideas?
Why don't you set up your models like it is suggested in the documentation here:
So your models would look something like this:
User Model
public function departments()
{
return $this->belongsToMany('path\to\your\model\Department');
}
Department Model
public function users()
{
return $this->belongsToMany(path\to\your\model\User);
}
Eloquent will join the two related model names in alphabetical order.So you don't need extra arguments when defining your relationship and Laravel also by default, makes model keys present on the pivot object. And then you can do something like this:
$department = path\to\your\model\Department::find(1);
foreach ($department->users as $user) {
echo $user;
}
For some reason, if I make the relationship the following - it works.
return $this->belongsToMany(Department::class, 'department_users')->orWhere('department_users.user_id', $this->id);
If anyone knows why, please let me know
I have 3 tables : hotels, hotels_data, hotels_types
Table hotels have id, type, stars, etc... type field is set as foreign key referencing type_id in hotels_types. I'm managing to get the correct data from hotels_data but have an empty result on getting hotels_types title and I don't understand why.
The code is the following :
class Hotel extends Eloquent {
public function getList() {
$data = Hotel::select('id','stars')->with('HotelData', 'HotelType')->paginate(10);
return View::make('hotels.index')->with('hotels', $data);
}
public function HotelData()
{
return $this->hasOne('HotelsData')->select('id','hotel_id','title');
}
public function HotelType()
{
return $this->hasOne('HotelType','type_id', 'type')->select('id','type_id','title');
}
}
You're using the wrong relationship for HotelType()
Your Hotel model should use the inverse of hasOne, which is belongsTo, because it contains the foreign key to HotelType (when a table contains a foreign key, it always belongs to the table being pointed to).
The following should work:
public function hotelType() {
return $this->belongsTo('HotelType','type', 'type_id')->select('id','type_id','title');
}
I've obtained the desired result with the following:
Hotel::select('hotels.*','hotels_types.title as type')
->join('hotels_types', 'hotels.type', '=', 'hotels_types.type_id')
->with('HotelData');