Laravel 5: no foreign key when saving related models - php

I have a simple one-to-one relationship between a User and a Profile, I'm trying to create a user and save their profile with the foreign key in one go and avoid having to pass the primary key and do two save() calls.
Laravel will try to insert the corresponding Profile values without the id pointing back to the user. What am I doing wrong ?
class User extends Model
{
public function profile()
{
return $this->hasOne('App\Profile');
}
}
class Profile extends Model
{
protected $table = 'user_profile';
public function user()
{
return $this->belongsTo('App\User');
}
}
class UserController extends Controller
{
public function create(Request $request)
{
$this->validate($request, [
...
]) ;
$user = new User() ;
$profile = new Profile() ;
$user->name = $request->input('name') ;
...
$profile->first_name = $request->input('first_name') ;
$profile->last_name = $request->input('last_name') ;
...
$user->profile()->save($profile) ;
// $profile->user()->save($user) ; // doesn't work
// $profile->user()->associate($user) ; // doesn't work
// $profile->save() ;
}
}

you need first to save the user
$user = new User;
$user->name = $request->input('name') ;
$user->save();
$profile = new Profile;
$profile->first_name = $request->input('first_name') ;
$user->profile()->save($profile);

The function name you are looking is "associate"
$user->profile()->associate($profile);
$user->save();

Related

PHP Laravel save() is not updating record

I am a beginner in laravel. I was updating records but I can't figure out what is wrong with my $student->save();
My controller code is as follows
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Student;
use PHPUnit\Framework\MockObject\Builder\Stub;
class HomeController extends Controller
{
public function read() {
$students = Student::all();
return view('read',['Students'=>$students]);
}
public function insert() {
return view('insert');
}
public function insertPost(Request $req) {
$student=new Student();
$student->Name = $req->input('name');
$student->Marks = $req->input('marks');
$student->save();
return redirect('/');
}
public function update($id) {
$student = Student::find($id);
return view('update',['Student'=>$student]);
}
public function delete($id) {
$student = Student::find($id);
$student->delete();
}
public function updatePost(Request $req) {
$student = Student::find($req->input('id'));
$student->Name=$req->input('name');
$student->Marks=$req->input('marks');
$student->save();
// Student::where('ID',$req->input('id'))
// ->update(['Name'=>$req->input('name'),
// 'Marks'=>$req->input('marks')]);
return redirect('/');
}
}
The Main main in updatePost(); is causing the records not updating
$student = Student::find($req->input('id'));
$student->Name=$req->input('name');
$student->Marks=$req->input('marks');
$student->save();
I changed the way of updating records to
Student::where('ID',$req->input('id'))
->update(['Name'=>$req->input('name'),
'Marks'=>$req->input('marks')]);
and it worked. But I wanted to know at which part I was making mistake in it.
You need to set your primary key to 'ID'
By default the primary key or PK name is 'id'
But in your code it changed to 'ID'
So you need to go to your User.php model class
and add this line
public $primaryKey = 'ID';
One thing you can try is using Laravel's update method. update will handle the save internally.
$student = Student::findOrFail($req->input('id')));
$student->update([
'Name' => $req->input('name'),
'Marks' => $req->input('marks'),
]);

How to get ID from a relationship table, Laravel

I have 4 table : Users, CompanyRegister, VoucherDetails, Addvoucher.
So the Authenticate Users Id will be submit as user_id in companyRegister table,and then companyRegister ID will be submit as company_id in Voucherdetails table, and lastly voucherDetails Id will be submit in addVoucher table as voucher_ID. I am new to using eloquent and also laravel, I cant understand why I cant get the id from voucherdetails and submit in addvoucher but I can get id from companyregister and submit in company_id in voucherdetails. I'm using the same method to get id but not work, I hope can get solution and explanation here,Thank you in advance!!
My users model
public function companyregisters()
{
return $this->hasOne('App\companyregisters');
}
public function voucherdetails()
{
return $this->hasMany('App\voucherdetails');
}
public function addvoucher()
{
return $this->hasMany('App\addvoucher');
}
public function roles()
{
return $this->belongsToMany('App\role');
}
public function hasAnyRoles($roles)
{
if($this->roles()->whereIn('name', $roles)->first()){
return true;
}
return false;
}
public function hasRole($role)
{
if($this->roles()->where('name', $role)->first()){
return true;
}
return false;
}
my companyregister model
public function User(){
return $this->belongsTo('App\User');
}
public function voucherdetails()
{
return $this->hasMany('App\voucherdetails');
}
my voucherdetails model
public function User(){
return $this->belongsTo('User');
}
public function companyregisters(){
return $this->belongsTo('App\companyregisters');
}
public function addvoucher()
{
return $this->hasOne('App\addvoucher');
}
my addvoucher model
public function User(){
return $this->belongsTo('App\User');
}
public function voucherdetails(){
return $this->belongsTo('App\voucherdetails');
}
my voucherdetailsController
public function store(Request $request){
$voucherdetail = new voucherdetails();
$voucherdetail->title = $request->input('title');
$voucherdetail->description = $request->input('description');
$voucherdetail->user_id = Auth::user()->id;
$id = Auth::user()->id;
$user = User::find($id);
$company = $user->companyregisters;
$companyId = $company->id;
$voucherdetail->company_id = $companyId;
$voucherdetail->save();
return redirect()->to('addvoucher');
}
my addvoucherController
public function store(Request $request){
$addvoucher = new addvoucher();
$addvoucher->voucherTitle = $request->input('voucherTitle');
$addvoucher->voucherCode = $request->input('voucherCode');
$addvoucher->user_id = Auth::user()->id;
//Here(the voucherdetails id cant get to submit in voucher_id)
$id = Auth::user()->id;
$user = User::find($id);
$voucher = $user->voucherdetails;
$voucherID = $voucher->id;
$addvoucher->voucher_id = $voucherID;
$addvoucher->save();
return redirect()->to('displayVouchers');
}
This code works because companyregisters is a hasOne relationship for which the docs say:
Once the relationship is defined, we may retrieve the related record
using Eloquent's dynamic properties.
public function companyregisters()
{
return $this->hasOne('App\companyregisters');
}
$company = $user->companyregisters; // ie this returns the single related record
$companyId = $company->id; // and it has an `id` property, all good here
However, this code fails because voucherdetails is a hasMany relationship for which the docs say:
Once the relationship has been defined, we can access the "collection"
of comments by accessing the comments property.
More info on collections
public function voucherdetails()
{
return $this->hasMany('App\voucherdetails');
}
$voucher = $user->voucherdetails; // ie this returns a "collection" of related records
$voucherID = $voucher->id; // this "collection" does NOT have an id property, but each record IN the collection does.
In summary, either your relationship is defined incorrectly (hasMany vs hasOne) or, you'll need to loop over the related records to get the id from each.

Trying to fill the intermediate table using attach() but getting "Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::attach()"

I have tables called users, places and user_place. users has a column called id that contains the id of the user and places has a column called place_id as well. The user_place table has 2 columns called user_id and place_id and I'm trying to automatically populate them with the corresponding ids. I read I have to use attach() function after setting up the relationships which I believe I have done but I might be wrong. Here they are:
class PlaceController extends Controller
{
public function likePlace(Request $request){
$placeId = $request['placeId'];
$userId = $request['userId'];
$user = User::where('id', $userId)->first();
$place = new Place();
$place->place_id = $placeId;
$place->save();
$user->places()->attach($place);
}
}
User model:
class User extends \Eloquent implements Authenticatable
{
use AuthenticableTrait;
public function places(){
return $this->hasMany('App\Place');
}
}
Place mode:
class Place extends Model
{
public function user(){
return $this->belongsToMany('App\User');
}
}
In a Many to Many relationship, you should define both relationships like the following:
User.php
class User extends \Eloquent implements Authenticatable
{
use AuthenticableTrait;
public function places()
{
return $this->belongsToMany('App\Place', 'user_place', 'user_id', 'place_id');
} // ^^^^^^^^^^^^
}
Note: Given that your intermetiate table name doesn't follow the naming convention we specified so Laravel knows where table to look up.
Place.php
Notice that you mentioned that the primmary key of your Place model is place_id, and this also scapes from the Laravel convention you should specify it:
protected $primaryKey = 'place_id'; // <----
class Place extends Model
{
public function user()
{
return $this->belongsToMany('App\User', 'user_place', 'place_id', 'user_id');
}
}
So now in your controller:
class PlaceController extends Controller
{
public function likePlace(Request $request)
{
$placeId = $request['placeId'];
$userId = $request['userId'];
$user = User::where('id', $userId)->first();
$place = new Place();
$place->place_id = $placeId;
$place->save();
$user->places()->attach($place);
}
}
Side note
As I side note, you could save a couple of line replacing some sentences with their equivalent:
$userId = $request['userId'];
$user = User::where('id', $userId)->first();
Using the find() method, this is equal to:
$user = User::find($request['userId']);
Then, you could create your related object using the static method create of an Eloquent model so this:
$placeId = $request['placeId'];
$place = new Place();
$place->place_id = $placeId;
$place->save();
Is equal to this:
$place = Place::create(['place_id' => $request['placeId']]);
Then your controller will be reduced to this:
class PlaceController extends Controller
{
public function likePlace(Request $request)
{
$user = User::find($request['userId']);
$place = Place::create(['place_id' => $request['placeId']]);
$user->places()->attach($place);
}
}

No query results for model [App\Project] in Laravel 5.2 how to fix

Hi I need pass Project Model id as project_id to My Task Model table. this is My TaskController
public function store(Request $request)
{
$task = new Task;
$task->task_name = $request->input('name');
$task->body = $request->input('body');
$task->assign = $request->input('status');
$task->priority = $request->input('status');
$task->duedate = date("Y-m-d", strtotime($request->input("date")));
// Find the project with the given id
$project = Project::findOrFail($request->get('project_id'));
// This will set the project_id on task and save it
$project->tasks()->save($task);
}
this is My form action route regarding to store task data in projects folder blade file is show.blade.php
<form method="post" action="{{ route('tasks.store') }}">
this is Task Model
class Task extends Model
{
protected $fillable = ['task_name', 'body', 'assign','priority','duedate','project_id'];
public function scopeProject($query, $id)
{
return $query->where('project_id', $id);
}
public function projects()
{
return $this->belongsTo('App\Project');
}
this is Project Model
class Project extends Model
{
protected $fillable = ['project_name','project_notes','project_status','color','group'];
//
public function tasks(){
return $this->hasMany('App\Task');
}
but I got this error massage here
No query results for model [App\Project].
how can i fix this one?
Laravel model assumes your primary key is id. if you have different primary key in that case please define it in your model.
protected $primarykey = "project_id"; // or whatever it is
2nd - i think you should use your foreign key name in 2nd parameter of relationship functions.
return $this->hasMany('App\Task','foregin_key_name');
return $this->belongsTo('App\Project','foreign_key_name');

Save object with foreign keys in laravel

I use PHP, Laravel 5.2 and MySQL.
During user registration, I need to create a new Patient. But, Patient has user id, contact id and guardian id(foreign keys).
When I try to save() the patient, I get the following exception:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'patient_id' in
'field list' (SQL: update users set patient_id = 0, updated_at =
2016-06-07 12:59:35 where id = 6)
The problem is that I DO NOT have patient_id column. Instead I have patientId.
I don't know how to fix this issue. Any help will be appreciated. I can include the migration files if this is important.
UserController.php
public function postSignUp(Request $request)
{
$this->validate($request,[
'email' => 'required|email|unique:users',
'name' => 'required|max:100',
'password' => 'required|min:6'
]);
$guardian = new Guardian();
$guardian->guardianId = Uuid::generate();;
$guardian->save();
$contact = new Contact();
$contact->contactId = Uuid::generate();
$contact->save();
$user = new User();
$user->email = $request['email'];
$user->name = $request['name'];
$user->password = bcrypt($request['password']);
$user->save();
$patient = new Patient();
$patient->patientId = (string)Uuid::generate();
$patient->user()->save($user);
$patient->contact()->save($contact);
$patient->guardian()->save(guardian);
$patient->save();
Auth::login($user);
// return redirect()->route('dashboard');
}
Patient.php
class Patient extends Model
{
protected $primaryKey='patientId';
public $incrementing = 'false';
public $timestamps = true;
public function user()
{
return $this->hasOne('App\User');
}
public function contact()
{
return $this->hasOne('App\Contact');
}
public function guardian()
{
return $this->hasOne('App\Guardian');
}
public function allergies()
{
return $this->belongsToMany('App\PatientToAllergyAlert');
}
public function medicalAlerts()
{
return $this->belongsToMany('App\PatientToMedicalAlert');
}
}
User.php
class User extends Authenticatable
{
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function patient()
{
return $this->belongsTo('App\Patient');
}
}
Contact.php
class Contact extends Model
{
protected $table = 'contacts';
protected $primaryKey = 'contactId';
public $timestamps = true;
public $incrementing = 'false';
public function contact()
{
return $this->belongsTo('App\Patient');
}
}
Guardian.php
class Guardian extends Model
{
protected $table = 'guardians';
protected $primaryKey = 'guardianId';
public $timestamps = true;
public $incrementing = 'false';
public function contact()
{
return $this->belongsTo('App\Patient');
}
}
You have not defined relationships correctly. First of all, fill in table fields into $fillable array in Patient, Contact, Guardian classes (just like in User class).
If you want to use hasOne relationship between Patient and User, you're gonna need user_id field on patients table. You can alternatively use belongsTo relationship.
If you want to use custom column names, just specify them in relationship methods:
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id');
// alternatively
return $this->belongsTo('App\User', 'user_id', 'id');
}
Just go through documentation without skipping paragraphs and you will get going in a few minutes :)
https://laravel.com/docs/5.1/eloquent-relationships#defining-relationships
Also, this will not work:
$patient = new Patient();
$patient->patientId = (string)Uuid::generate();
$patient->user()->save($user);
new Patient() only creates the object, but does not store it in DB, so you will not be able to save relationships. You need to create the object and store it to DB to avoid this problem:
$patient = Patient::create(['patientId' => (string)Uuid::generate()]);
$patient->user()->save($user);
...
// or
$patient = new Patient();
$patient->patientId = (string)Uuid::generate();
$patient->save();
$patient->user()->save($user);
...
When you're setting up your relationship, you can to specify the name of the primary key in the other model. Look here.
I'm not sure, but I think you relationships are not defined properly.

Categories