I am trying to return a list of fixtures that have a team associated to them. The home team field in the fixtures table references the id on the team table and the same for the away team field:
teams
-------
id (int, primary)
name (varchar[255])
fixtures
-------
id (int, primary)
hometeam (int - references `id` on `teams`)
awayteam (int - references `id` on `teams`)
date (datetime)
I have a fixtures and team model seperately, at the moment I am only able to return the team id in the fixtures table and not the name associated to it from the team table. I believe this is because the magic models look for the same name as the field name, i.e. team instead of hometeam or awayteam.
Is there anyway I can get this to wor with eloquent or does it need an old fashioned join?
Thanks in advance
At first, Eloquent search the key with the structured name. If your foreign key is different or parent model key isn't id, you can define the fields in relation.
Ref: One To Many (Inverse)
/**
* Get the team that owns the fixture.
*/
public function team()
{
// hometeam: foreign_key
// id: parent model primary key
return $this->belongsTo('App\Team', 'hometeam', 'id');
}
Related
How to combine 3 Many to Many tables with eloquent in the laravel
Hi Friends, please help me,
How do you combine the following three tables with eloquent in laravel?
The following table structure and figures:
(https://i.stack.imgur.com/BfISA.jpg)
Member table structure
{member_id: primary key, name, created_at, updated_at}
List table structure
{list_id: primary key, member_id: foregn key, price_id: foreign key, created_at, updated_at}
Price table structure
{price_id: primary key, name_price, created_at, updated_at}
Can you give me sample source code for view.blade, controller and model.
Thank you, your answer is very meaningful
in your member model add relationship function list(). Then in your list model add relationship function price then use below code
app\Member.php
public function list(){
return $this->hasMany('App\List', 'member_id');
}
app\List.php
public function price(){
return $this->hasMany('App\Price', 'price_id');
}
in your controller
$result = Member::with(['list.price'])->get();
it will give you a member list with list and price table data.
I have a Person model with demogographic information, Orgs model with organization information and an OrgPerson model that is effectively a pivot table with additional fields. I've crated OrgPerson to extend Model instead of Pivot because it worked better with my setup.
--- Edit: table structures ---
Table: person (Model: Person)
PK: personID
(other demographic fields)
defaultOrgID (FK -> orgID) // the org that will be displayed/referenced by default
// changeable by user with multiple orgs
Table: organization (Model: Org)
PK: orgID
(other org-demographic fields)
Table: org-person (Model: OrgPerson -- functionally a pivot table)
PK: personID, orgID
(other combo-demographic fields for the person with respect to the org)
--- End of table structures edit ---
I acknowledge that the OrgPerson model is the capture of a many-to-many relationship. However, I need to be able to grab the "combo-demographic" data (stored in the OrgPerson record) for the person related to the defaultOrgID.
Because a Person can belong to multiple Orgs, I want the orgperson record for $this person but for the "default" Org as stored in $person->defaultOrgID.
My Person model had the following relation defined in v5.5 and it returned what I wanted via $person->load('orgperson') or via eager loading.
public function orgperson()
{
return $this->hasOne(OrgPerson::class, 'personID', 'personID')
->where('orgID', $this->defaultOrgID);
}
Running code like:
$person = Person::find(x);
$person->load('orgperson')
Returns a Person model with a non-null orgperson model in the relationships list.
After upgrading to v5.6 and performing some testing, I'm finding that this relation is not populating. I haven't gotten it to populate in any of my testing and I cannot find any reason why it would be different.
add a migration to give orgperson table a primary key
Schema::table('orgperson', function (Blueprint $table) {
$table->bigIncrements('id');
});
so you can do something like this
public function orgperson()
{
return $this->hasOne(OrgPerson::class, 'defaultOrgID', 'personID')
}
I'd like your input on this.
I have a Customer_table with a field name. I have another table called Reservation_table with a Customer_name field.
How can I relate them in such a way that I'd see all the bookings by the specific customer?
In Reservation_table you should have a field(foreign key) userid in order ta have a user for each reservation.
You can using primary key - foreign key relationship to relate/join those two tables. Also, instead of having a 'Customer_name' field as your FK referring to 'name' field in 'Customer_table' table, it is better to have an id (unique) generated for each customer; This way you can have an efficient way of uniquely identifying and relating customer across tables; can save space on Database side as well. Hope this helps!
If you want to use eloquent you must first define a relationship.
One reservation belongs to a user. Here is how to define the relationships:
Inside the Reservation model:
public function user()
{
return $this->belongsTo('App/User'); //User model
}
To define the inverse you do the following:
Inside User model:
public function reservations()
{
return $this->hasMany('App/Reservation'); // Reservation Model
}
Now you can do the following in your controller:
$reservations = Auth::user()->reservations;
Now you have all reservations by the currently logged in user.
I am not sure if I got the question right so ask away.
I have a pivot table set up with the following columns:
table - contributions
=====================
id - int, pk
user_id - int, fk
resource_id - int, fk
linked_id - int, fk
...
This basically creates a many-to-many relationship between users and resources. Now, the thing is, linked_id is also a foreign key which points to the ID in the resources table. In most cases, linked_id will just be null and won't be a problem. But sometimes, I want a contribution to be linked to a user, a resource, and one other resource.
In my Resource model I have the following code:
public function contributions()
{
return $this->hasMany('Contribution');
}
But this won't return anything if I'm calling this on a Resource which has its ID in the linked_id column. Is there some way to return all the rows/relations when the resource's ID is found in either the resource_id or the linked_id column? (Somehow has a second $foreignKey value).
Hm, options:
1) create a custom query where you retrieve the Resource, join the contributions table where you match resource_id or linked_id on the current id from the Resource object.
something like:
SELECT R.*
FROM resources AS R
INNER JOIN contributions AS C ON (
C.`resource_id` = R.`resource_id`
OR C.`linked_id` = R.`resource_id`
)
WHERE R.`id` = {$Resource->id}
GROUP BY R.`id`
2) create a second relation method, linkedContributions, which matches the linked_id column.
public function linkedContributions()
{
return $this->hasMany('Contribution', 'linked_id');
}
and retrieve the data:
$Resource = Resource::with(['contributions', 'linkedContributions'])->find(1);
3) other idea; you are currently able to link only 1 resource to another resource. If you create an extra table + hasMany 'linkedResources' relation, you will be able to link multiple resource back to the current Resource. (and skip this problem here altogether)
I modified my contributions function inside my Resource model like so:
public function contributions()
{
return DB::table('contributions')
->where('resource_id', '=', $this->id)->orWhere('linked_id', '=', $this->id)
->join('resources', function($join) {
$join
->on('resources.id', '=', 'contributions.resource_id')
->orOn('resources.id', '=', 'contributions.linked_id');
})
->groupBy('contributions.id')
->select(
'contributions.id', 'contributions.description', 'contributions.created_at', 'resources.id AS tileId', 'resources.name AS tileName',
'users.id AS userId', 'users.username')
->get();
}
The linked contributions will now show up in both models without having to create two entries for each link.
I've got a situation in a project where I need to form a relationship between a primary key on one table and an indexed column (not the primary key) on another. Here's a sample of the database layout:
courses table
id
level
resources table
id
courses_resources table
course_level
resource_id
In my CourseResource model I have the following:
public function courses(){
return $this->belongsToMany('Course', 'courses_resources', 'resource_id', 'course_level');
}
Which works fine.
Then in my Course model I have:
public function resources(){
return $this->belongsToMany('CourseResource', 'course_resources', 'course_level', 'resource_id');
}
Which doesn't work. When I look at the last query performed on the database, it appears Laravel is searching the course_level column using the course's ID. That makes sense, but is there any way to use the level column for this relationship?
Eloquent BelongsToMany depends on PKs, so there is no way to do that with its methods.
You need custom relation object for this, that will check for given field, instead of primary key.
A quick and hacky solution would be this:
// Course model
public function getKey()
{
$relation = array_get(debug_backtrace(1, 2), '1.object', null);
if (method_exists($relation, 'getForeignKey')
&& $relation->getForeignKey() == 'courses_resources.course_level')
{
return $this->getAttribute('level');
}
return parent::getKey();
}
However if you would like to use it in production, do some extensive testing first.