save one to one relationship. foreign keys in both tables - laravel

I have two tables as follow:
CREATE TABLE pets(
id int NOT NULL AUTO_INCREMENT,
user_id int,
any_data varchar(255),
foreign key (user_id) references users(id),
primary key(`id`)
);
CREATE TABLE users(
id int NOT NULL AUTO_INCREMENT,
pet_id int,
any_data varchar(255),
foreign key (pet_id) references pets(id),
primary key(`id`)
);
And my models have the next:
USERS:
public function relatedPet() {
return $this->hasOne("Pet", "pet_id");
}
PETS:
public function relatedUser() {
return $this->belongsTo("User", "user_id ");
}
I want to save an User and relate to an existent pet, but i don't know how to do that:
$user= new User(array("any_data"=>"Hi, this is a test"));
$pet = Pet::find(1);
How can I create the relation between the two objets?

First your users table does not need a pet_id. Drop it. Then
Users Model
public function pet()
{
return $this->hasOne('App\Pet'); // Changed form hasMany to hasOne
}
Pet Model
public function user()
{
return $this->belongsTo('App\User');
}
Now create a new User
$user = \App\User::create($data); // You need to set $fillable property
$pet = \App\Pet::findOrfail($id)
$pet->user()->associate($user);
$pet->save();
Examples:
$user = \App\User::findOrFail($id);
$pet = $user->pet
// Inserting a new user and a pet
$anotherUser = \App\User::create($data);
$anotherPet = new \App\Pet($data);
$anotherUser->pet()->save($anotherPet);
$pet = \App\Pet::findOrFail($id);
$user = $pet->user
// Inserting a new pet, a user and then associating them
$anotherPet = \App\Pet::create($data);
$anotherUser = \App\User::create($data);
$anotherPet->user()->associate($anotherUser);
$anotherPet->save()

Related

Laravel - for some reason, max breaks my query

I have this piece of code:
$query = Student::whereHas('statusuri', function($q) use ($status) {
$q->latest('status_student.id')->take(1)
->where('status_id', $status)
->whereNotNull('status_id');
});
and it works fine, but I don't necessarily get the desired result.
I tried changing the first line to max (so I don't filter all my records then do a limit 1), I just get the highest ID from the beginning - like this:
$query = Student::whereHas('statusuri', function($q) use ($status) {
$q->max('status_student.id')
->where('status_id', $status)
->whereNotNull('status_id');
});
but then my query breaks.
For some reason, I get this:
Unknown column 'students.id' in 'where clause' (SQL: select max(`status_student`.`id`) as aggregate from `statusuri` inner join `status_student` on `statusuri`.`id` = `status_student`.`status_id` where `students`.`id` = `status_student`.`student_id`)
Why does my query break after I do this change?
Thanks.
Tables:
students
id bigint(20)
//other non-related data
statusuri
id bigint(20)
nume VARCHAR(255)
status_student
id int(11)
student_id int(10)
status_id int(10)
stare_stagiu_id int(11)
created_at timestamp
updated_at timestamp
statusuri() from Student
public function statusuri()
{
return $this->belongsToMany(Status::class, 'status_student')
->withPivot('id', 'data_inceput', 'data_sfarsit', 'document', 'status_id', 'stare_stagiu_id')
->withTimestamps();
}
Status and StatusStudent classes
class StatusStudent extends Model
{
protected $table = 'status_student';
protected $fillable = ['id', 'student_id', 'status_id', 'stare_stagiu_id'];
}
class Status extends Model
{
protected $table = 'statusuri';
public $fillable = ['nume'];
}
Your relations are messed up. The query is trying to use a column from the student table, but the student table is not available in said query as it is not joined. See this fiddle to see what goes wrong in the SQL.
http://sqlfiddle.com/#!9/52c96fa/6
In the end, I'd do it like this if I understood you correctly:
In StatusStudent.php (Model):
public function student() {
return $this->hasOne(Student::class, 'id', 'student_id');
}
In Controller:
public function stackoverflowtest() {
//Set teststatus
$status = 1;
//Get the latest status of all users - and if that status is correct, retrieve into array
$latest = DB::select( DB::raw("SELECT max(id) as id, student_id FROM status_student group by student_id"));
$array = [];
foreach ($latest as $l) {
$status_id = StatusStudent::whereId($l->id)->whereStatusId($status)->first();
if ($status_id) {
array_push($array, $status_id);
}
}
//$array now holds all the StatusStudent, simply user ->student to get the student related to said status, example below
if($array) {
dd($array[0]->student);
return $array;
} else {
return 'No match';
}
}
First, we get all latest records for each user IF the status is correct. Then, we simply get the Student from the status_student table via the relation.

Laravel Eloquent relationships with 3 Table

Laravel 3 Table
table_user
id
name
table_barang
id
iduser
name
statusbarang_id
table_statusbarang
id
name
My code UserModels:
public function BarangModels()
{
return $this->hasMany(BarangModels::class, 'iduser');
}
My code BarangModel :
public function UserModels()
{
return $this->belongsTo(UserModels::class);
}
public function StatusBarangModels()
{
return $this->hasOne(StatusBarangModels::class, 'idstatusbarang');
}
My Code StatusBarangModels :
public function BarangModels()
{
return $this->belongsTo(BarangModels::class);
}
My Code Usercontroller
public function showdetail($id)
{
$value = UserModels::find($id);
return view('user/detailuser', compact('value'));
}
And, I want to select barangmodels (id, name) statusbarangmodels (name)
thank you
First you need to add primary key of BarangModel as foreign key in StatusBarangModels for the relationship that you define in models. After adding key use the following code.
UserModels::with(['BarangModels'=>function($item){
$item->with(['StatusBarangModels'=>function($query){
$query->select('statusbarang_id','name');
}])->select('id','name');
}])->get();
You need to select foreign key in nested relationships so that eloquent can match primary and foreign key in tables.
This will work.
Thank you

yii 1.1.x ar relation for composite forign key

I have three tables
Boooking
id, -> primary key
name
Ticket
booking_id, (primary key)
seq , (primary key)
name
TicketAllocation
id, (primary key)
booking_id, (foreign key)
seq, (foreign key)
name,
date
Ticket table has primary key as composite of(booking_id,seq), and foreign key booking_id from Booking table.
and it works as foreign key in TicketAllocation table.
How can i define relation in both Ticket and TicketAllocation table so i can use AR relation to get related data.
Hii it you can simply use this
Ticket Model
public function relations()
{
return array(
'ticketToBoooking' => array(self::BELONGS_TO, 'Boooking', 'booking_id'),
);
}
TicketAllocation Model
public function relations()
{
return array(
'ticketAllcationToBooking' => array(self::BELONGS_TO, 'Boooking', 'booking_id'),
);
}

relationship one to many only working one side

i have a relationship one to many not working in one side.
My tables
`seguro_carro` (
`id_seguro` INT NOT NULL AUTO_INCREMENT,
`matricula` VARCHAR(8) NOT NULL,
`validade` DATE NOT NULL,
`preco` DECIMAL(12,3) NOT NULL,
`tipo_seguro` INT NOT NULL,
`cliente` INT NOT NULL
)
`tipo_seguro_carro` (
`id_tipo_seguro` INT NOT NULL AUTO_INCREMENT,
`descricao` VARCHAR(50) NOT NULL
)
Models:
SeguroCarro.php
public function tipoSeguro()
{
return $this->belongsTo('App\TipoSeguroCarro', 'id_tipo_seguro');
}
TipoSeguroCarro.php
public function seguros()
{
return $this->hasMany('App\SeguroCarro','tipo_seguro');
}
i can do TipoSeguroCarro::find(x)->seguros but not the other side like SeguroCarro::find(x)->tipoSeguro
and i can't understand why this is happening..
someone ?
thanks
You should pass tipo_seguro attribute instead of id_tipo_seguro, because Your foreign key is tipo_seguro in both relationships.
Some explanation due to request:
https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Model.html#method_belongsTo
BelongsTo belongsTo( string $related, string $foreignKey = null, string $otherKey = null, string $relation = null)
https://laravel.com/api/5.2/Illuminate/Database/Eloquent/Model.html#method_hasMany
HasMany hasMany( string $related, string $foreignKey = null, string $localKey = null)
Both belongsTo and hasMany accepts second parameter as foreign key. So basicly, You have two fields involved - first is Your primary key (id_tipo_seguro) and second is foreign key (tipo_seguro). As mentioned before, both methods accept foreign key as second parameter.

Laravel 5 Eloquent, double one-to-one save (get Id before save)

$profile = new Profile;
$user = new User;
$user['profile_id'] = $profile['id'];
$profile['user_id'] = $user['id'];
$profile->save();
$user->save();
So I have the relationships setup using "hasOne" in both Models files. These are NOT NULL FOREIGN KEYS so I need to define the id relationship immediately. But ['id'] is not available until after save. How can I do these 2 save operations at the same time?
You should have the foreign key in only one of the tables, and define the other relationship as belongsTo
EDIT
If you keep the user_id in the profiles table, then add this to your user model
public function profile()
{
return $this->hasOne('App\Profile');
}
then you can do this
$user = new User;
$user->save();
$user->profile()->save(new Profile());

Resources