Laravel 4 Relations belongsTo on multiple tables - php

I'm trying to do a stystem of comments and posts with laravel 4 where 2 type of "user" can comments. For 2 type of "user" means that i have a table User and a table Teams and my expectations are that both can let comment on the posts of the opposite. Let'go with the logic that i used untill now:
Schema tables:
User Table
Table | Users
id - integer autoincrement
fullname - string 20
Team table
Table | Teams
id - integer autoincrement
fullname - string 50
Posts table
Table | Posts
id - integer autoincrement
text - text
id_poster - integer
type_id - integer // if is 1 the id_poster filed belongs to user else if 2 belongs to team
Comments Table
Table | Comments
id - integer autoincrement
id_post - integer
id_poster - integer
id_type - integer
text - text
And now let's go with the relations:
Users relation
Class User extends Eloquent {
protected $table = "users";
function posts() {
return $this->hasMany('Post','id_poster');
}
function comments() {
return $this->hasMany('Comment','id_poster');
}
}
Team relation
Class Team extends Eloquent {
protected = $table = "teams";
function posts() {
return $this->hasMany('Post','id_poster');
}
function comments() {
return $this->hasMany('Comment','id_poster');
}
}
Posts relation
Class Post extends Eloquent {
protected $table = "posts";
function users() {
$this->belongsTo('User','id_poster');
}
function teams() {
return $this->belongsTo('Team','id_poster');
}
function comments() {
return $this->hasMany('Comment','id_post');
}
}
Comments relation
Class Comment extends Eloquent {
protected $table = "comments";
function posts() {
return $this->belongsTo('Post','id_post');
}
function teams() {
return $this->belongsTo('Team','id_poster');
}
}
with this kind of relations i can get posts and comments about just an individual category:
example i do the results for the users posts and comments
$posts = new Post;
$get_post = $posts->with('users','comments.users')->where('type_id','=',1)->get();
i can display
users posts and users comments OR
teams posts and teams comments
but not
Users posts and teams / users comments
Team posts and users / teams comment
The datas need it for my output about the comments are:
- id_poster
- fullname
- id_type
- text
In few words my question is:
What i have to change and why for do appear the comments of both the "user"?

Related

How define relation hasManyThrough

I have tables:
users
- id
- name
- company_id
companies
- id
- company_name
watched_objects
- id
- user_id
- object_id
- type
Now I want to get all watched companies for a user.
So query should looks:
SELECT
companies.*
FROM companies
JOIN watched_objects ON watched_objects.object_id = companies.id
WHERE watched_objects.user_id = 1
How should I define relations?
I try this:
class User
{
public function watched()
{
return $this->hasManyThrough('App\Company', 'App\WatchedObject', 'user_id', 'id');
}
}
But query is:
SELECT
companies.*,
watched_objects.user_id
FROM companies
INNER JOIN watched_objects ON watched_objects.id = companies.id
WHERE watched_objects.user_id = 1
How I can change watched_objects.id to watched_objects.object_id.
If your treating object_id as company id, then the relation is considered to be many to many. Then table watched_objects will be the third table kept the relation of user and company.
class User {
public function watched() {
return $this->belongsToMany('App\Company', 'watched_objects', 'user_id', 'object_id');
}
}
In order to find the watched companies of user 1, you can use the following code.
$watched_companies = User::find(1)->watched;
To get all watched companies by a user you can do like this:
$watches=WatchedObject::where(['user_id'=>Auth::user()->id])->with('company')->get();
foreach($watches as $watch)
{
print_r($watch->company->company_name);
}
Relation:
Company hasMany watched objects:
public function watches()
{
return $this->hasMany('App\WatchedObject','object_id');
}
and belongsTo in watchedObject Model:
public function company()
{
return $this->belongsTo('App\Company','object_id');
}

How can i get First table records on base of third table by using laravel 5 eloquent model

Requested tables are listed below:
**User Table**
id, name
1, vehicle person name
2, renter person name
**Vehicle Table**
id, user_id, vehicle_name
1, 1, My car
**Booking Table**
id, renter_id, vehicle_id
1, 2, 1
User Model
public function renter() {
return $this->hasMany(Booking::class, 'renter_id');
}
public function vehicleBook() {
return $this->hasManyThrough(Booking::class, Vehicle::class);
}
Booking Model
public function user() {
return $this->belongsTo(User::class, 'renter_id');
}
Vehicle Model
public function user() {
return $this->belongsTo(User::class);
}
My Controller
$renters = Auth::user()->renter()->get();
$owners = Auth::user()->vehicleBook()->get();
// In Loop
$renter->user->name; // renter person name
$owner->user->name; // vehicle person name
Result
On base of booking Table i want to get renter person and vehicle person name using Laravel 5 ORM.
I have done that using two calls but i want to know if there is any way to get result using one call ?
You could do something like this. It will reduce the number of lines, but will increase the number of queries.
$user = User::find(Auth::user()->id)->with('renters')->with('vehicleBooks')->first();

HasManyThrough with another relationship in Laravel 5.2

I have 3 models:
Tournament, Category, Team
A Tournament hasMany Category
A Category hasMany Team
Tables:
Tournament: Only attributes
Category: id, tournament_id, name
Teams: id, category_id, name
I would like to get all teams from a tournament by: $tournament->teams
I tried :
public function teams()
{
return $this->hasManyThrough(Team::class,CategoryTournament::class);
}
Then I need an extra relation of my team: team->category->name;
but the result of this HasManyThrough has no relationship....
Any Idea???
In Category model :
public function team ()
{
return $this->hasMany('App\Teams');
}
In Teams model :
public function category ()
{
return $this->belongsTo('App\Category', 'category_id');
}
I think should be like this, Try.
According to laravel documentation :
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
With this you can add relationship :
public function posts()
{
return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
}

Relationship between a hasMany and belongsToMany in Laravel

I have two Models - InternalNotesThread and InternalNotes
class InternalNotesThread extends Model {
public function notes(){
return $this->hasMany('App\InternalNotes', 'thread_id', 'id');
}
}
class InternalNotes extends Model {
public function thread() {
return $this->belongsTo('App\InternalNotesThread');
}
public function users()
{
return $this->belongsToMany('App\User', 'user_notes_tagged', 'internal_notes_id', 'user_id');
}
}
Also, InternalNotes is mapped to User with a relation of belongsToMany.
DB Structure:
internal_notes_thread:
id - int
ticket_id (FK) - int
name - string
internal_notes:
id - int
thread_id (FK) - int
notes - string
user_notes_tagged: (Many to many with internal_notes and User)
internal_notes_id (FK) - int
user_id (FK) - int
For every note, there might be some user tagged in it.
How can I directly relate this relationship with the internal_notes_thread???
I get the data with this:
$data = InternalNotesThread::with('notes')->where('ticket_id', '=', $id)->get()->toArray();
But, in the notes array, I am not able to get the users tagged in that note
How can I get all the data in one go???
You're not eager loading the users, so they don't show up in your ->toArray() array.
Try this:
$data = InternalNotesThread::with('notes.users')
->where('ticket_id', '=', $id)
->get()
->toArray();

Has many through

A Venue has many Subscriptions.
A Subscription has many Subscribers (User).
Theres a pivot table, containing the relation between user_id and subscription_id.
How can I get all Subscribers from a Venue?
I have tried with:
class Venue {
/**
* Members
*/
public function members() {
return $this->hasManyThrough('App\User', 'App\Subscription');
}
}
But it fails with MySQL error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.subscription_id' in 'on clause' (SQL: select `users`.*, `sub
scriptions`.`venue_id` from `users` inner join `subscriptions` on `subscriptions`.`id` = `users`.`subscription_id` where `
users`.`deleted_at` is null and `subscriptions`.`venue_id` = 1)
How my Subscription model look:
`Subscription`
class Subscription extends Model {
protected $table = 'subscriptions';
/**
* Subscripers
*/
public function subscribers() {
return $this->belongsToMany('App\User');
}
/**
* Venue
*/
public function venue() {
return $this->belongsTo('Venue');
}
}
Simple question: Why are you using a third model for Subscriptions? It sounds like a normal n:m relation between User and Venue, as already written in the comments above.
class User {
public function venues() {
return $this->belongsToMany('App\Venue');
}
}
class Venue {
public function users() {
return $this->belongsToMany('App\User');
}
}
This constellation actually needs three tables, which are (i gave each model a column name):
users
- id
- name
venues
- id
- name
user_venue
- user_id
- venue_id
But to access the relations, you can simply use the Eloquent magic:
// List of all venues (as Venue models) that are in relation with User with id $id
$venues = User::find($id)->venues()->get();
// Returns the alphabetically first user that has a relation with Venue with id $id
$user = Venue::find($id)->users()->orderBy('name', 'asc')->first();
If you need to store additional information in the pivot table (e.g. when the relation has been established), you can use additional pivot fields:
user_venue
- user_id
- venue_id
- created_at
class User {
public function venues() {
return $this->belongsToMany('App\Venue')->withPivot('created_at');
}
}
class Venue {
public function users() {
return $this->belongsToMany('App\User')->withPivot('created_at');
}
}
// Returns the date of the relations establishment for the alphabetically
// first Venue the User with id $id has a relation to
$created_at = User::find($id)->venues()->orderBy('name', 'asc')->first()->pivot->created_at;
I've never tried to do whatever you are trying to do there, because it seems (with the current information) conceptually wrong. I also don't know if it is possible to set up an own model for a pivot table, but I think it should work if the pivot table has an own primary id column. It could probably be helpful if you've a third model that needs to be connected with a connection of two others, but normally that doesn't happen. So try it with pivot tables, like shown above, first.
Alright, I still don't see a good use case for this, but I can provide you a query that works. Unfortunately I wasn't able to get an Eloquent query working, but the solution should be still fine though.
class Venue {
public function members($distinct = true) {
$query = User::select('users.*')
->join('subscription_user', 'subscription_user.user_id', '=', 'users.id')
->join('subscriptions', 'subscriptions.id', '=', 'subscription_user.subscription_id')
->where('subscriptions.venue_id', '=', $this->id);
if($distinct === true) {
$query->distinct();
}
return $query;
}
}
The relation can be queried just as normal:
Venue::find($id)->members()->get()
// or with duplicate members
Venue::find($id)->members(false)->get()

Categories