Laravel one to many relationship results - php

Hello i am trying to create one to many relationship. One user from user table could have many companies, on other side company could have only one user.
my migration for company table is
public function up()
{
Schema::create('companies', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('address');
$table->string('city');
$table->string('state');
$table->string('contact_person');
$table->string('phone');
$table->string('industry');
$table->string('website');
$table->integer('id_user')->unsigned();
$table->foreign('id_user')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
}
my user model is
/**
* Get the posts for the user.
*/
public function companies()
{
return $this->hasOne('App\Company','user_id');
}
my company model is
public function users()
{
return $this->belongsTo('App\User','id');
}
i am trying to get all companies for specific user
try with whereHas but no data in relation object
$results = Company::whereHas('users', function ($query) {
$query->where('users.id',1);
})->get();
Where is my error?

First thing you should change is companies() relation. It has to be hasMany, not hasOne:
public function companies()
{
return $this->hasMany('App\Company');
}
Then get user with all his companies:
$result = User::where('id', $id)->with('companies')->first();
Or, if you want to use Company model like in your example and get only companies:
$result = Company::where('user_id', $id)->get();
Also, you're using id_user in migration. Change it to user_id.

Related

Laravel: Order a model by "Has One Of Many" relationship

I have a customer model that has many contacts. I defined a relationship to get the most recent contact of the customer using the "Has One Of Many" relationship in Laravel 8:
Models
class Customer extends Model
{
use HasFactory;
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function latestContact()
{
return $this->hasOne(Contact::class)->ofMany('contacted_at', 'max')->withDefault();
}
}
class Contact extends Model
{
use HasFactory;
protected $casts = [
'contacted_at' => 'datetime',
];
public function customer()
{
return $this->belongsTo(Customer::class);
}
}
Migration (contact model)
class CreateContactsTable extends Migration
{
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->softDeletes();
$table->foreignID('customer_id');
$table->string('type');
$table->dateTime('contacted_at');
});
}
}
In my view, I want to show all customers and order them by their latest contact. However, I can't figure out how to do that.
I tried to achieve it via the join method but then I obviously get various entries per customer.
$query = Customer::select('customers.*', 'contacts.contacted_at as contacted_at')
->join('contacts', 'customers.id', '=', 'contacts.customer_id')
->orderby('contacts.contacted_at')
->with('latestContact')
Knowing Laravel there must be a nice way or helper to achieve this. Any ideas?
I think the cleanest way to do this is by using a subquery join:
$latestContacts = Contact::select('customer_id',DB::raw('max(contacted_at) as latest_contact'))->groupBy('customer_id');
$query = Customer::select('customers.*', 'latest_contacts.latest_contact')
->joinSub($latestContacts, 'latest_contacts', function ($join){
$join->on([['customer.id', 'latest_contacts.customer_id']]);
})
->orderBy('latest_contacts.latest_contact')
->get();
More info: https://laravel.com/docs/8.x/queries#subquery-joins
I suspect there is an issue with your migration, the foreign key constraint is defined like this:
Check the documentation:
https://laravel.com/docs/8.x/migrations#foreign-key-constraints
Method 1: define foreign key constraint
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->foreignId('consumer_id')->constrained();
$table->string('type');
$table->dateTime('contacted_at');
$table->timestamps();
$table->softDeletes();
});
}
Method 2: define foreign key constraint
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('customer_id');
$table->foreign('customer_id')->references('id')->on('customers');
$table->string('type');
$table->dateTime('contacted_at');
$table->timestamps();
$table->softDeletes();
});
}

Eloquent many to many relationship is always empty

I know this question has been asked a lot but all answers didn't seem to work for me - or at least the questions I found were about the pivot table.
I have a many to many relationship (User - Appointment) which is joined by the pivot table "apointment_user", see migrations below.
Schema::create('appointment_user', function (Blueprint $table) {
$table->unsignedInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->unsignedInteger('appointment_id')->nullable();
$table->foreign('appointment_id')->references('id')->on('appointments');
$table->primary(['user_id','appointment_id']);
$table->timestamps();
});
Schema::create('appointments', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->dateTime('date');
$table->string('location');
$table->dateTime('departure');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->date('last_login')->nullable();
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
class User extends Model {
protected $with = ['appointments'];
public function appointments() : BelongsToMany {
return $this->belongsToMany(Appointment::class);
}
}
class Appointment extends Model {
public function users() : BelongsToMany {
return $this->belongsToMany(User::class);
}
}
I have a user with the ID 1 and about 10 appointments, which I do attach to the relationship in a seeder. The pivot table has 10 records, as intended (User ID is always 1).
However, if I dump my User object using dd(User::find(1)), the relationship is always an empty collection. However, a 1:n relationship (between a role works well).
Does anybody see what I'm missing? Any help is appreciated.
Many thanks and kind regards
Edit
I just tried some other kind of dumping. I've simply returned my User-Object as JSON-response and there the relationship is filled with 10 appointments... strange.
Though it seems that your table and column names are as Laravel would guess, have you tried expliciting the names?
class User extends Model {
protected $with = ['appointments'];
public function appointments() : BelongsToMany {
return $this->belongsToMany(Appointment::class, 'appointment_user', 'user_id', 'appointment_id');
}
}
class Appointment extends Model {
public function users() : BelongsToMany {
return $this->belongsToMany(User::class, 'appointment_user', 'appointment_id', 'user_id');
}
}

Laravel related model attributes are empty?

I'm trying to give ability on user to see his orders. I have created relationships but when i (dd) the result of the function, the related model attributes are empty.
I don't know what is wrong.
Here is my buyer function
//Buyer Orders
public function myOrders()
{
$user = User::find(auth()->user()->id);
$user = $user->products();
dd($user);// related model attributes shows empty
return view('myOrders')->with(compact('user'));
}
and here is my user
public function products()
{
return $this->hasMany(Products_model::class);
}
public function orders()
{
return $this->hasMany(Order::class);
}
public function allOrdersBuyerSeller()
{
return $this->hasMany(OrderProduct::class);
}
products_model
public function orders()
{
return $this->belongsToMany('App\Order', 'order_product');
}
public function user()
{
return $this->belongsTo('App\User');
}
User Migration
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Product Migration
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('pro_name');
$table->integer('pro_price');
$table->text('pro_info');
$table->integer('stock');
$table->integer('category_id');
$table->string('image')->nullable();
$table->timestamps();
$table->bigInteger('seller_id')->unsigned()->index();
$table->foreign('seller_id')->references('id')->on('users')->onDelete('cascade');
});
}
I would like to see the attributes of the table like price, name, info, img and etc.
Barring the comments about your code, the reason you're not seeing the result of your products query is that you're not passing a closure to the query.
$user = $user->products();
Currently, $user is a QueryBuilder instance. Until you use a closure, like first(), get(), paginate(), etc, you won't be able to see the rows. Modify your code to the following:
$products = $user->products;
// OR
$products = $user->products()->get();
If you omit the (), it will load the relationship using products()->get(), unless already loaded.
Edit: You likely need to include foreign keys to your relationships as the Model name won't match:
User.php
public function products(){
return $this->hasMany(Product_model::class, "seller_id", "id");
}
Probably best to review the contents of the documentation for Relationships; https://laravel.com/docs/5.8/eloquent-relationships. There's a lot of incorrect practices going on with your naming, querying, etc.

Laravel follower/following relationships

I am trying to make a simple follower/following system in laravel, nothing special, just click a button to follow or unfollow, and display the followers or the people following you.
My trouble is I can't figure out how to make the relationships between the models.
These are the migrations:
-User migration:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('email');
$table->string('first_name');
$table->string('last_name');
$table->string('password');
$table->string('gender');
$table->date('dob');
$table->rememberToken();
});
-Followers migration:
Schema::create('followers', function (Blueprint $table) {
$table->increments('id');
$table->integer('follower_id')->unsigned();
$table->integer('following_id')->unsigned();
$table->timestamps();
});
}
And here are the models:
-User model:
class User extends Model implements Authenticatable
{
use \Illuminate\Auth\Authenticatable;
public function posts()
{
return $this->hasMany('App\Post');
}
public function followers()
{
return $this->hasMany('App\Followers');
}
}
-And the followers model is basically empty, this is where I got stuck
I tried something like this:
class Followers extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
but it didn't work.
Also, I'd like to ask if you could tell me how to write the "follow" and "display followers/following" functions. I've read every tutorial I could find but to no use. I can't seem to understand.
You need to realize that the "follower" is also a App\User. So you only need one model App\User with these two methods:
// users that are followed by this user
public function following() {
return $this->belongsToMany(User::class, 'followers', 'follower_id', 'following_id');
}
// users that follow this user
public function followers() {
return $this->belongsToMany(User::class, 'followers', 'following_id', 'follower_id');
}
User $a wants to follow user $b:
$a->following()->attach($b);
User $a wants to stop following user $b:
$a->following()->detach($b);
Get all followers of user $a:
$a_followers = $a->followers()->get();

Laravel 5 pivot table project<->user

I find the pivot tables pretty complicated and I don't see what to do next or what I am doing wrong, I've found some tutorials but didn't help me in my needs.
I have a projects and users with a many-to-many relation.
One project hasMany users and One user hasMany projects.
What I have now leaves projects without a relationship to a user.
This is what I have so far:
Projects table
class CreateProjectsTable extends Migration {
public function up()
{
Schema::create('projects', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->date('completion_date');
$table->integer('completed')->default(0);
$table->integer('active')->default(0);
$table->timestamps();
});
}
Users table
class CreateUsersTable extends Migration {
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->integer('company_id');
$table->integer('project_id');
$table->integer('usertype_id')->default(0);
$table->string('username');
$table->string('password');
});
}
Project User table (pivot)
class CreateProjectUsersTable extends Migration {
public function up()
{
Schema::create('project_users', function(Blueprint $table)
{
$table->increments('id');
$table->integer('project_id')->references('id')->on('project');;
$table->integer('user_id')->references('id')->on('user');;
});
}
User model
public function projects() {
return $this->belongsToMany('App\Project', 'project_users', 'user_id', 'project_id');
}
Project model
public function users() {
return $this->belongsToMany('App\User', 'project_users', 'project_id', 'user_id');
}
Project controller
public function index(Project $project)
{
$projects = $project->with('users')->get();
dd($projects);
$currenttime = Carbon::now();
//return view('project.index', array('projects' => $projects, 'currenttime' => $currenttime));
return view('user.index', compact('projects'));
}
The relationship in your User model is not correct. You have to swap the keys.
public function projects() {
return $this->belongsToMany('App\Project', 'project_users', 'user_id', 'project_id');
}
Edit regarding latest comment:
Don't think about the pivot table, as long as you have your relations setup correctly, which I believe they are, Laravel handles all of that for you.
Now $projects->users does not make any sense because projects does not have users. projects is just a collection of Project. Each Project within that collection will have a users relation. You would have to iterate through the collection to view each Project's users.
foreach($projects as $project) {
foreach($project->users as $user) {
echo $user;
}
}

Categories