Seeding Relationship one to many in Laravel - php

I need to seed a relationship in Laravel, where each user has many devices
The User model
public function devices()
{
return $this->hasMany(Device::class);
}
The Device model
public function users()
{
return $this->belongsTo(User::class);
}
}
The device_user table
Schema::create('device_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('device_id')->unsigned()->index();
$table->foreign('device_id')->references('id')->on('devices')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
The seeder
factory(App\Device::class, 20)->create()->each(function(App\Device $device) {
$device->users()->attach([
rand(1,5),
rand(6,15),
rand(16,20),
]);
});
But, when I run the migration with seeder, I get this message
Call to undefined method Illuminate\Database\Query\Builder::attach()
Please, help

attach for many to many relationships, you don't need device_user table for one to many relationship, in one to many you should create a column with name user_id in device table and just it. after that you can insert data in device table with user_id. and get user relationship with
Device::user()->get();

Related

Laravel Eloquent where statement returns no attributes

So from my previous post, I was advised to start using Eloquent models, which I did.
My end goal, is to print out specific gifts, that belongs to that specific box.
Migrations:
gift_items:
public function up()
{
Schema::create('gift_items', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->float('unit_price');
$table->integer('units_owned');
});
}
gift_campaigns:
public function up()
{
Schema::create('gift_campaigns', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->foreignId('user_foreignK')->constrained('users');
$table->integer('gift_item_count')->nullable();
$table->string('status');
$table->date('dispatch_date');
$table->date('delivery_date');
});
}
Pivot table:
public function up()
{
Schema::create('campaigns_gifts', function (Blueprint $table) {
$table->foreignId('gift_id')->constrained('gift_items');
$table->foreignId('campaign_id')->constrained('gift_campaigns');
});
}
Controller:
function box($id){
$data = Campaign::with('gifts')->where('id', $id)->get();
return view('DBqueries.boxView', ['data'=>$data]);
}
Error that I receive using this way:
Seems like the updated version is trying to call the gift_campaigns table id, instead of the pivots table campaign_id.
Once again, I need that Request $id would match the pivots table campaign_id, and print out all of the gifts that this specific id holds
First of all as I sense the campaigns_gifts is a pivot table for campaigns and gifts having a Many-to-Many relation. You are doing it completely against the conventions of Laravel.
You generally do not use a Model for pivot table.
You generally do not fetch data from the pivot table directly. Instead use the relation on one of the related Models.
Note: Laravel does allow a Model for a Pivot, and you can query the pivot table directly, just check the documentation.
The correct way:
Pivot
Make a pivot table (that you already have) with column gift_id and campaign_id. i.e., the convention for naming keys as [table_name_singular]_[primary_key_on_table]
Model
One each model, define relationship for the other data as:
Gift.php Model:
public function campaign() {
return $this->belongsToMany(Campaign::class, 'campaign_gift');
}
Campaign.php Model:
public function gifts() {
return $this->belongsToMany(Gift::class,'campaign_gift');
}
since gift have a hasMany relation, the gifts table must contain a foreign key to campaigns table named campaign_id (same as the one on pivot).
Controller
Now in your controller:
function box($id){
$data = Campaign::where('id',$id)->with('gifts')->get();
return view('DBqueries.boxView', ['data'=>$data]);
}
You don't need to tell Laravel which columns, tables etc are you referring to, as long as you follow the conventions, Laravel will magically do things that otherwise would have been much more painful.

Laravel eloquent get details from related table

I don't understand how to return info back to blade template if I have two related tables:
First table is standard Laravel 'users' table
Second table:
Schema::create('recipes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('code', 10);
$table->string('description');
$table->float('size');
$table->bigInteger('created_by')->unsigned();
$table->string('status')->default('pending');
$table->boolean('deleted');
$table->timestamps();
$table->foreign('created_by')
->references('id')
->on('users')
->onDelete('cascade');
}
Than I have two Controllers: User and Recipe
Recipe have
public function user()
{
return $this->belongsTo(\App\User::class);
}
and User have
public function recipes()
{
return $this->hasMany(\App\Recipe::class);
}
actual output looks like this (RecipesController):
$recipes = Recipe::latest()->paginate($perPage);
return view('admin.recipes.index', compact('recipes'));
everything looks OK but column created_by contain users primary key witch is integer. How can I display users name? This is something like inner join but is it possible to do that in eloquent? Or I completely misunderstanding those public functions in a Model?
Your user relationship in your Recipe model is missing the foreignKey:
public function user()
{
return $this->belongsTo(\App\User::class, 'created_by');
}
You can then eager load the users with your recipes in the controller:
$recipes = Recipe::with('user')->latest()->paginate($perPage);
return view('admin.recipes.index', compact('recipes'));
And finally you can access the user in the view:
#foreach($recipes as $recipe)
{{ $recipe->user->name }}
#endforeach
You can read more about the inverse of the one-to-many relationship in the docs.

Is ti posible to get value name from related table this way

Ok so I need to get data from the table this way but I would like to get
Vehicle Maker name too
I tried using join or
just doing auth()->user()->vehicles->VehicleMaker but it doesn't work
Migration of Table Vehicle
Schema::create('vehicles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id');
$table->bigInteger('category_id');
$table->bigInteger('vehicle_maker_id');
$table->string('name');
$table->double('price', 8 , 2);
$table->year('manufacture_year');
$table->bigInteger('mileage');
$table->string('vehicle_image');
$table->boolean('admin_verification')->nullable();
$table->timestamps();
});
Migration of vehicle_makers
Schema::create('vehicle_makers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
Controller
public function show(){
$vehicles = auth()->user()->vehicles; -- what shoul i add here
return view('/home', [
'vehicles' => $vehicles
]);
}
Edit
I forget to mention that I already made a relationship and they work in artisan tinker when I try to do something like this:
Vehicles->find(1)->VehicleMaker
What I want is to do is
auth()->user()->vehicles and get vehicle teble with vahicle_maker name not id so some kind of join that would work in this case
Okay base on Laravel Model Relationship.
You first need to create a migration.
Vihicle Migration
Schema::create('vehicles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('category_id');
$table->unsignedBigInteger('vehicle_maker_id');
$table->string('name');
$table->double('price', 8 , 2);
$table->year('manufacture_year');
$table->bigInteger('mileage');
$table->string('vehicle_image');
$table->boolean('admin_verification')->nullable();
$table->timestamps();
});
I used unisignedBigInteger to determine it is a foreign key or you can also use index().
In your model you should place what relation ship you will use. In your case I assumed you are using One To Many Relationship. So that your user model should look like this:
User Model
...
public function vehicles() {
return $this->hasMany(Vehicle::class);
}
So that you can use the convention auth()->user()->vehicles;.
Note: the auth()->user()->vehicles; return a array of object you can loop it in foreach.
Vehicle Model
public function user() {
return $this->belongsTo(User::class);
}
In when you have this in your model you can use it 2 way.
In your controller you can call the relationship of those 2.
Controller
$vehicles = auth()->user()->vehicles;
dd($vehicles);
INFO
You can also refer to this tutorial.
EDIT
Controller
$vehicles = auth()->user()->vehicles();
foreach($vehicles as $vehicle) {
dd($vehicle->VehicleMaker);
}
Note: The $vehicles is returning an array of object. So you can loop it through foreach loop to throw a single instance.
There should be a relationship between the user and vehicles then another relationship between vehicles and vehicle_makers. If you already created your models(Vehicle, VehicleMaker) with their migrations, You can do the following
//add this to your User model.
public function vehicle(){
return this->belongsTo(App\Vehicle);
}
// add this to your Vehicle model
public function user(){
return this->hasMany(App\Vehicle); // implying that a user can have many vehicles
}
//add this to your vehicleMaker model
public function vehicle(){
return this->belongsTo(App\Vehicle);
}
When that is done, you can use Laravel's lazy loading to fetch relationships. You can do something like
$vehicles = auth()->user()->vehicle
return view('/home', [
'vehicles' => $vehicles
]);

How to use many to many polymorphic relation in Laravel 5.2

I am reading laravel 5.2 docs to implement many to many polymorphic relation in my Laravel Application.
I have Many models like Blog, Question, Photo etc and I want to have Tagging system for all of them.
I have created Tag table with following schema
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('slug')->unique();
$table->timestamps();
});
Below is pivot table schema. Pivot table name is entity_tags
Schema::create('entity_tags', function (Blueprint $table) {
$table->increments('id');
$table->integer('tag_id')->unsigned();;
$table->integer('taggable_id')->unsigned();
$table->string('taggable_type');
$table->timestamps();
$table->index('tag_id');
$table->index('taggable_id');
$table->index('taggable_type');
});
This is the relationship defined in Tag model for Question model
public function questions()
{
return $this->belongsToMany('App\Question', 'entity_tags', 'tag_id', 'taggable_id');
}
And the following relation is defined in Question Model
public function tags()
{
return $this->belongsToMany('App\Tag', 'entity_tags', 'taggable_id', 'tag_id');
}
Now I want to define Many to Many Polymorphic relationship as defined in Laravel 5.2.
My Question are
how I can define them?
Should I remove the Many to Many
relationship and only define Many to Many polymorphic relationship ?
If yes, then how to manage custom pivot table name ?
Also is it required to suffix column name with word able that are part of
polymorphic relationship ?
Use return $this->morphToMany() instead of belongsToMany, and in the Tag model, write 3 methods with return $this->morphedByMany() for the reverse relationship.
You only need polymorphic definitions, no need for the many to many normal ones. The name of the pivot table is with 'able' at the end by the default convention but you can name it anything you want.
no, you don't have to have a word with 'able' at the end, it's just a way to define that it's something more general, you can name it anything you want.
Naming is based on some default convention by Laravel.
Update:
You have the following pivot table schema:
Schema::create('entity_tags', function (Blueprint $table) {
$table->increments('id');
$table->integer('tag_id')->unsigned();;
$table->integer('entity_id')->unsigned();
$table->string('entity_type');
$table->timestamps();
$table->index('tag_id');
$table->index('entity_id');
$table->index('entity_type');
});
and the tags table:
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('slug')->unique();
$table->timestamps();
});
So you want to create the relationships for blog, video and question tables / models:
Tag.php Model:
public function questions()
{
return $this->morphedByMany('App\Question', 'entity', 'entity_tags');
}
public function blogs()
{
return $this->morphedByMany('App\Blog', 'entity', 'entity_tags');
}
public function videos()
{
return $this->morphedByMany('App\Video', 'entity', 'entity_tags');
}
Question.php / Blog.php / Video.php
public function tags()
{
return $this->morphToMany('App\Tag', 'entity', 'entity_tags');
}

PHP Laravel 5.2 belongs to

I have 3 tables Users, Profiles, and Friends.
Users contains users, obviously.
Then I got the Profiles and Friends table (see below).
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('picture')->nullable();
$table->string('status')->nullable();
$table->string('text')->nullable();
$table->boolean('show_sex');
$table->boolean('show_dob');
$table->timestamps();
});
}
public function up()
{
Schema::create('friends', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id_sender')->unsigned();
$table->integer('user_id_receiver')->unsigned();
$table->foreign('user_id_sender')->references('id')->on('users');
$table->foreign('user_id_receiver')->references('id')->on('users');
$table->integer('status'); // 1 = friends, 2 = under validation
$table->timestamps();
});
}
As you can see, i created some foreign keys that relates to the Users table.
The Friends table contains all friendships between users (the status field will determine if the friendship is under validation or validated).
I have the default User model that comes with Laravel 5.2 and was wondering, how can I easely get all the friendships, that belongs to the signed user?
Could I use something like belongsTo() or something to easely get all friendrequests where the user_id_receiver field is the same as the signed users id? I didn't quiet understand the documentation for hasOne or belongsTo.. Would be nice if someone could clearify how it actually works.
Thanks in advance.
Yes, you should use One-to-one relation between User and Profile models and One-to-many relation between User and Friend models. Add this to both models - Friend and Profile:
public function user()
{
return $this->belongsTo('app\User');
}
And add this to User model:
public function profile()
{
return $this->hasOne('app\Profile');
}
public function friend()
{
return $this->hasMany('app\Friend');
}
And then you could use Eloquent to get data:
$signedUserId = Auth::user()->id;
$currentUserFriendRequests = Friend::where('user_id_receiver', $signedUserId)->get();
I hope this will be helpful.

Categories