I need to make a HasManyThough relation where the middle Model holds the foreign keys of both Models.
Here is detail:
Migrations:
Schema::create('carriers', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Schema::create('shipping_zones', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Schema::create('shipping_rates', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('shipping_zone_id')->unsigned()->index();
$table->integer('carrier_id')->unsigned()->index();
$table->decimal('rate', 20, 6);
});
Now I need something like
$carrier->shippingZone()
Is there any easy way to get this?
As per your migrations you need Many To Many relation rather than the HasManyThough relation.
Carrier.php
public function shippingZones()
{
return $this->belongsToMany('App\ShippingZone', 'shipping_rates);
}
You can access all shipping zones related to the carrier using, $carrier->shippingZones.
If you need to chain the query you can use $shippingZones = $carrier->shippingZones()->orderBy('id')->get(); here
If you need to use HasManyThough you would have to change the migrations. here
Related
I think I am doing this correctly. I have a users, profile, and application table. Below are the migrations. I think I am linking them correctly in the migration but need advice to make sure. 1 user can have 1 profile but many applications.
User Table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Profile Table
public function up()
{
Schema::create('profile', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->unsigned();
$table->string('address')->nullable();
$table->string('apt')->nullable();
$table->string('city')->nullable();
$table->string('state')->nullable();
$table->string('zipcode')->nullable();
$table->string('homephone')->nullable();
$table->string('mobile')->nullable();
$table->string('occupation')->nullable();
$table->boolean('over18')->nullable();
$table->string('homechurch')->nullable();
$table->string('homechurchcity')->nullable();
$table->string('pastor')->nullable();
$table->string('howoftenattend')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
Application
public function up()
{
Schema::create('pilgrim_application', function (Blueprint $table) {
$table->id();
$table->string('besttimetocall');
$table->string('nickname');
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
$table->foreignId('profile_id')->constrained('profile')->onDelete('cascade');
$table->timestamps();
});
Does your migration work at the moment?
First check your migration file order, for example
0000_user
0001_profile
1000_ pilgrim_application
1001_app_two
in case of multiple applications you could begin the migration with a different number for grouping files in a list, this can be handy if you want to create multiple applications.
Also, is it necessary to specify the relations user and profile in the pilgrim_application migration?
Through relationships in your models you can also access the pilgrim_application from the user model and vice versa.
$user->profile->pilgrim_application
I'm wondering if this is possible. I have 3 models.
Users
TenantPreferances
PropertyAdverts
I'm trying to find out if I can do a query like so.
Find all tenants, whose preferences, match the currently signed in users properties.
The 3 databases are like so
User Model
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('userType');
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
PropertyAdverts
Schema::create('property_adverts', function (Blueprint $table) {
$table->increments('id');
$table->string("photo");
$table->string('address');
$table->string('county');
$table->string('town');
$table->string('type');
$table->string('rent');
$table->string('date');
$table->string('bedrooms');
$table->string('bathrooms');
$table->string('furnished');
$table->longText('description');
$table->integer('user_id'); //Landlord ID
$table->timestamps();
});
Tenant Preferances
Schema::create('tenant_preferances', function (Blueprint $table) {
$table->increments('id');
$table->string('county');
$table->string('type');
$table->string('rent');
$table->string('bedrooms');
$table->string('bathrooms');
$table->boolean('status')->default('0');
$table->integer('user_id'); //Tenant ID
$table->timestamps();
});
Yes, that is possible. You need to dig in on relations. You can then create a function to define the relation on you model:
function propertyAdverts() {
return $this->hasMany(PropertyAdverts::class);
}
You can access the relation from the user model by using $user->propertyAdverts. If you want to eager load them you can do so:
User::with('propertyAdverts')->find(3);
But notice that Laravel does not do a regular join by default. It first fetches all users, and then fetches all propertyAdverts using a single query using a in statement.
I have rooms in hospitals. Each room has beds with numbers. I want to assign beds to patients. How can I handle this in an easy way:
rooms migration:
Schema::create('rooms', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('floor');
$table->text('description');
$table->timestamps();
});
beds migration:
Schema::create('beds', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('quality');
$table->string('charge');
$table->integer('room_id')->unsigned();;
$table->foreign('room_id')->references('id')->on('rooms')
->onUpdate('cascade')->onDelete('cascade');
$table->boolean('status');
$table->timestamps();
});
reservations migration:
Schema::create('reservations', function (Blueprint $table) {
$table->increments('id');
$table->date('date_in');
$table->date('date_out');
$table->boolean('status');
$table->integer('patient_id')->unsigned();
$table->foreign('patient_id')->references('id')->on('patients');
$table->integer('bed_id')->unsigned();
$table->foreign('bed_id')->references('id')->on('beds');
$table->timestamps();
});
How can I check for available beds? Get the available beds? Be sure the bed is available. How can I use events and listeners to make the whole thing work?
pluck() retrieve a Collection containing the values of a single column.
Here, it retrieves a Collection of reservation bed_id:
$reserved = Reservation::pluck('bed_id)->all();
The whereNotIn method verifies that the given column's value is not contained in the given array:
$bed_available = Bed::whereNotIn('id' , $reserved)->get();
This query gives you all the bed whose id is not available in that collection $reserved , which i think is your requirement .
I have 2 tables Manufacturers and Suppliers ,and they have Many-to-Many relation
Schema::create('manufacturers', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Schema::create('suppliers', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('location');
$table->timestamps();
});
so i created a pivot table called "manufacturer_supplier" and it works fine.
Schema::create('manufacturer_supplier', function (Blueprint $table) {
$table->increments('id');
$table->integer('manufacturer_id')->unsigned()->index();
$table->integer('supplier_id')->unsigned()->index();
$table->timestamps();
$table->foreign('manufacturer_id')->references('id')->on('manufacturers')->onDelete('cascade');
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('cascade');
});
My confusion comes from adding a new table "devices"
Schema::create('devices', function (Blueprint $table) {
$table->increments('id');
$table->string('serial')->unique();
$table->string('name');
$table->integer('supplier_id')->unsigned()->nullable();
$table->integer('manufacturer_id')->unsigned()->nullable();
$table->text('notes')->nullable();
$table->timestamps();
$table->foreign('supplier_id')->references('id')->on('suppliers')->onDelete('cascade');
$table->foreign('manufacturer_id')->references('id')->on('manufacturers')->onDelete('cascade');
});
where i want to have a one-to-many relation with each of suppliers and manufacturers , so i would have a select list of manufacturers and then populate the next list from with suppliers from Pivot table that relate to the selected manufacturer.
currently my "device" model has the following relations which it relate them to the original table not the pivot so it doesn't work
//5
public function manufacturer(){
return $this->belongsTo('App\Manufacturer');
}
//6
public function supplier(){
return $this->belongsTo('App\Supplier');
}
I haven't done that before so i'm curious to know what will be the best fix for this to work.
Thanks a lot ,
If you want all suppliers associated with a single manufacturer you could get them using the many-to-many relation.
$suppliersList = $supplier->manufacturer()->suppliers();
howerver I don't understand why a device should be associated with a single supplier .... but that's up to you.
I have a scenario with Articles and Categories where each article can have only one category through a CategoryGroup.
This means the article can have more than one category but only one unique category from each category_group. Or, to put it another way, the article can have only one category from each category_group.
Do I model this scenario at the level of relationships? Or is this a matter of using custom validation?
This seems like a hasOneThrough scenario but this doesn't exist. So what's the workaround?
I have tried a many-to-many relationship between articles and categories but how do I constrain the article from having more than one of each category type while attaching categories to single articles?
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->string('slug');
$table->timestamps();
});
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->text('description');
$table->string('slug');
$table->string('handle');
$table->integer('category_group_id')->index()->nullable();
$table->timestamps();
});
Schema::create('article_category', function (Blueprint $table) {
$table->integer('article_id')->unsigned();
$table->integer('category_id')->unsigned();
$table->primary(['article_id', 'category_id']);
$table->timestamps();
});