Laravel find records through intermediate table - php

I have 3 models:
User
Company
Enquiry
A user can own more than one company, a company can only belong to one user. An enquiry can belong to many companies and a company can have many enquiries.
The migrations look as follows:
User migration
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('contact_number');
$table->longText('address')->nullable();
$table->integer('postal_code');
$table->string('activation_token')->nullable();
$table->boolean('active')->default(false);
$table->enum('type', ['Admin', 'End User', 'Service Provider', 'Broker']);
$table->string('password')->nullable();
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
Company Migration
Schema::create('companies', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('service_provider_id')->nullable();
$table->unsignedInteger('broker_id');
$table->string('name');
$table->string('email')->unique()->nullable();
$table->string('contact_number');
$table->longText('address')->nullable();
$table->integer('postal_code');
$table->enum('status', ['Confirmed', 'Declined', 'New'])->default('New');
$table->timestamps();
$table->softDeletes();
});
Schema::table('companies', function (Blueprint $table) {
$table->foreign('service_provider_id')->references('id')->on('users');
$table->foreign('broker_id')->references('id')->on('users');
});
Enquiries Migration
Schema::create('enquiries', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('end_user_id');
$table->unsignedInteger('category_id');
$table->string('title');
$table->longText('description');
$table->integer('radius');
$table->enum('status', ['New', 'In Progress', 'Complete'])->default('New');
$table->timestamps();
});
Schema::table('enquiries', function (Blueprint $table) {
$table->foreign('end_user_id')->references('id')->on('users');
$table->foreign('category_id')->references('id')->on('categories');
});
CompanyEnquiry Migration
Schema::create('company_enquiry', function (Blueprint $table) {
$table->integer('company_id')->unsigned()->index();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$table->integer('enquiry_id')->unsigned()->index();
$table->foreign('enquiry_id')->references('id')->on('enquiries')->onDelete('cascade');
$table->primary(['company_id', 'enquiry_id']);
});
I have set up the various relationships in their respective models.
What I'm trying to achieve is query the database to retrieve only those enquiries which belong to the user via the company.
How can I achieve this?

Something like this (add the real model, relation names ans columns):
$enquiries = Enquiries::whereHas(['companies' => function($query){
$query->whereHas(['user' => function($query){
$query->where('id', $user_id);
}]);
})
->get();

You could do it this way with shorter code.
$enquiries = Enquiries::whereHas('companies.user', function($query) use($user_id){
$query->where('id', $user_id);
})->get();

Related

Laravel Eloquent how to make one-to-any relationship

I have model 'Transaction' which represent a message to be send, and the transaction shall have a relationship called 'recipients', each recipient might be a 'Group' Or a 'Person'.
The relationship is (One transaction has many recipients)
What type of eloquent relationship should I used?
How to implement that?
Transaction:
Schema::create('transactions', function (Blueprint $table) {
$table->id();
$table->enum('destination_type', DestinationType::getValues());
$table->foreignId('user_id')->constrained('users');
$table->timestamps();
});
Recipient:
Schema::create('recipients', function (Blueprint $table) {
$table->id();
$table->integer('recipient_id');
$table->string('recipient_type');
$table->timestamps();
});
Profile:
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->enum('type', ProfileType::getValues());
$table->string('username');
$table->string('arabic_name')->nullable();
$table->string('english_name');
$table->string('email')->nullable()->unique();
$table->string('mobile')->nullable();
$table->string('avatar')->nullable();
$table->timestamps();
});
Group:
Schema::create('groups', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained('users');
$table->string('name');
$table->timestamps();
});

Foreign key not being created

I'm trying to create a foreign key in the teachers table. after migration, all the columns were there, but the foreign key was not created
First, I have created two tables, which are the users table and the courses table.
if(! Schema::hasTable('users')) {
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->string('password');
$table->string('remember_token')->nullable();
$table->timestamps();
});
}
if(! Schema::hasTable('courses')) {
Schema::create('courses', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('slug')->nullable();
$table->text('description')->nullable();
$table->decimal('price', 15, 2)->nullable();
$table->string('course_image')->nullable();
$table->date('start_date')->nullable();
$table->tinyInteger('published')->nullable()->default(0);
$table->timestamps();
$table->softDeletes();
$table->index(['deleted_at']);
});
}
Then i created another table called 'teachers' with foreign keys
if(! Schema::hasTable('teacher')) {
Schema::create('teacher', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('course_id')->unsigned();
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
$table->string('teachers_image')->nullable();
$table->text('education')->nullable();
$table->text('contact')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
after the migration i can see the tables was there but the foreign key was not created
try this
if(! Schema::hasTable('teacher')) {
Schema::create('teacher', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedInteger('course_id');
$table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
$table->string('teachers_image')->nullable();
$table->text('education')->nullable();
$table->text('contact')->nullable();
$table->timestamps();
$table->softDeletes();
});
}

Base table or view not found laravel pivot table

Posts table looks like.
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->string('slug')->unique();
$table->string('image')->default('default.png');
$table->text('body');
$table->boolean('is_approved')->default(false);
$table->boolean('status')->default(false);
$table->integer('view_count')->default(0);
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade')->unsigned()->index();
$table->timestamps();
});
User table.
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id')->default(2);
$table->string('name');
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('image')->default('default.png');
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->text('about')->nullable();
$table->rememberToken();
$table->timestamps();
});
When run php artisan:migrate got the error.
I can't find it.
There is my post_users table.
Schema::table('post_users', function (Blueprint $table) {
$table->integer('post_id')->unsigned();
$table->integer('user_id');
$table->foreign('post_id')
->references('id')->on('posts')
->onDelete('cascade')->unsigned()->index();
});
enter image description here
In PostUsers Model define table name
class PostUsers extends Model {
public $table = "post_users";
Update:
Shouldn't
Schema::table('post_users', function (Blueprint $table) {
$table->integer('post_id')->unsigned();
$table->integer('user_id');
$table->foreign('post_id')
->references('id')->on('posts')
->onDelete('cascade')->unsigned()->index();
});
be
Schema::create('post_users', function (Blueprint $table) {
$table->integer('post_id')->unsigned();
$table->integer('user_id');
$table->foreign('post_id')
->references('id')->on('posts')
->onDelete('cascade')->unsigned()->index();
});
If you're going to create a new table you must use Schema::create

Using whereHas eloquent relationship query

I have the following tables :
Users
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('username');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->integer('role_id')->unsigned();
$table->foreign('role_id')->references('id')->on('roles');
Areas
Schema::create('areas', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('location_id')->unsigned();
$table->foreign('location_id')->references('id')->on('locations')->onDelete('cascade');
$table->timestamps();
area_user
Schema::create('area_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('area_id')->unsigned();
$table->foreign('area_id')->references('id')->on('areas');
});
Buildings
Schema::create('buildings', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('symbol')->nullable();
$table->integer('area_id')->unsigned();
$table->foreign('area_id')->references('id')->on('areas')->onDelete('cascade');
$table->integer('building_type')->unsigned();
$table->foreign('building_type')->references('id')->on('building_types');
$table->timestamps();
});
User Model:
public function areas()
{
return $this->belongsToMany('App\Area');
}
Area Model:
public function users(){
return $this->belongsToMany('App\User');
}
Building Model:
public function area(){
return $this->belongsTo('App\Area','area_id');
}
How can i write a query in User model that return all Buildings assigned to a user through his assigned areas (area_user table)
I tried this , but it returning an error
Building::whereHas('area', function ($q) {
$q->whereHas('users', function ($q) {
$q->where('id', auth()->id());
});
})->get();
Error:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous (SQL: select * from `buildings` where exists (select * from `areas` where `buildings`.`area_id` = `areas`.`id` and exists (select * from `users` inner join `area_user` on `users`.`id` = `area_user`.`user_id` where `areas`.`id` = `area_user`.`area_id` and `id` = 11))) (View: C:\xampp\htdocs\hse\resources\views\observations\form_observation.blade.php) (View: C:\xampp\htdocs\hse\resources\views\observations\form_observation.blade.php)
You can resolve the ambiguity by specifying the table in your where clause:
Change
$q->where('id', auth()->id());
To
$q->where('users.id', auth()->id());

How to attach many to many relationship in Laravel?

I have 2 table 1st products belongsToMany Colors and 2nd Colors belongsToMany products
I made my table like this
Product Table
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('image');
$table->string('stock');
$table->string('title');
$table->string('slug')->unique();
$table->string('gender');
$table->text('description');
$table->integer('price');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')
->onDelete('restrict')
->onUpdate('restrict');
$table->dateTime('published_at');
});
and Color Table with relationship
Schema::create('colors', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Schema::create('color_product', function (Blueprint $table) {
$table->integer('color_id')->unsigned()->index();
$table->foreign('color_id')->references('id')->on('colors')
->onDelete('restrict')
->onUpdate('restrict');
$table->integer('product_id')->unsigned()->index();
$table->foreign('product_id')->references('id')->on('products')
->onDelete('restrict')
->onUpdate('restrict');
$table->timestamps();
});
I am trying to add more color in in 1 product like this
public function addproductdetailspost(Request $request, $product){
$product = product::where('slug', $product)->firstorfail();
$color = color::where('name', $request->color)->firstOrCreate();
$color->name = $request->color;
$color->save();
$product_id = $product->id;
$color_id = $color->id;
$product->colors()->attach($product_id);
return Redirect::back()->with('status', 'Post Success');
}
It's not working, I am getting this error
Type error: Too few arguments to function Illuminate\Database\Eloquent\Builder::firstOrNew(), 0 passed in C:\xampp\htdocs\swimwear2\app\Http\Controllers\AdminController.php on line 109 and at least 1 expected
It's the wrong direction.
$color->products()->attach($product_id);

Categories