Create hasmany relatioship in vehicle model and insert data in vehicle and vehicle_staff table. data successfully insert in vehicle table but when store in vehicle_staff following error appear.
Error Comes:
Type error: Argument 1 passed to
Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an
instance of Illuminate\Database\Eloquent\Model, array given, called in
E:\xampp\htdocs\laravel-projects\collegeaccounting\app\Http\Controllers\Transport\VehicleController.php
on line 53
Vehicle Staff Table Schema:
Schema::create('vehicle_staffs', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->unsignedInteger('vehicles_id');
$table->unsignedInteger('staffs_id');
$table->boolean('status')->default(1);
});
Has Many Relationship on Vehicle Model:
class Vehicle extends BaseModel
{
protected $fillable = ['created_by', 'last_updated_by', 'number', 'type', 'model', 'description', 'status'];
public function staff(){
return $this->hasMany(Staff::class);
}
}
Store Function:
public function store(AddValidation $request)
{
$request->request->add(['created_by' => auth()->user()->id]);
$vehicle = Vehicle::create($request->all());
if ($request->has('staffs_id')) {
$staffs = [];
foreach ($request->get('staffs_id') as $staff) {
$staffs[$staff] = ([
'vehicles_id' => $vehicle->id,
'staffs_id' => $staff
]);
}
$vehicle->staff()->save($staffs);
}
$request->session()->flash($this->message_success, ' Created Successfully.');
return redirect()->route($this->base_route);
}
It seems you are creating many to many relationships, that is to say, a vehicle can belongs to many staffs, and a staff can have many vehicles. So, vehicle_staffs is a intermediate table (or pivot table) between vehicle model and staff model.
For Vehicle model, you should change the staff method to:
public function staff(){
return $this->belongsToMany(Staff::class, 'vehicle_staffs', 'vehicles_id', 'staffs_id');
}
To update many to many relationships, you can attach the staff ids to vehicle:
$vehicle->staff()->attach($staffIds);
and the code change of your store function:
if ($request->has('staffs_id')) {
$staffIds = $request->get('staffs_id');
$vehicle->staff()->attach($staffIds);
}
I don't know what version of Laravel you are using, so I assume you are on Laravel 5.x.
You should probably use saveMany() if you want to save more than one object. It takes a Collection or an array of Models as a parameter.
From the documentation:
If you need to save multiple related models, you may use the saveMany method:
$post = App\Post::find(1);
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
Related
maybe someone know how to insert pivot table in Laravel 8 automatically every i insert counselings table?
I have Model Counseling n to n Problem,
Input form
counselings table
problems table
Counselings Model
Problem Model
Controller
public function create()
{
return view('admin.counseling.create', [
'title' => 'Tambah Bimbingan dan Konseling',
'students' => Student::all(),
'problems' => Problem::all()
]);
}
public function find_nis(Request $request)
{
$student = Student::with('student_class', 'counselings')->findOrFail($request->id);
return response()->json($student);
}
public function store(Request $request)
{ dd($request->all());
$counseling = new Counseling();
$counseling->student_id = $request->student_id;
$counseling->user_id = Auth::user()->id;
$counseling->save();
if ($counseling->save()) {
$problem = new Problem();
$problem->id = $request->has('problem_id');
$problem->save();
}
}
You can insert into a pivot table in a few different ways. I would refer you to the documentation here.
Attaching
You may use the attach method to attach a role to a user by inserting
a record in the relationship's intermediate table:
Example:
$problem->counselings()->attach($counseling->id);
Sync
You may also use the sync method to construct many-to-many
associations. The sync method accepts an array of IDs to place on the
intermediate table. Any IDs that are not in the given array will be
removed from the intermediate table.
Example:
$problem->counselings()->sync($counselingsToSync);
Toggle
The many-to-many relationship also provides a toggle method which
"toggles" the attachment status of the given related model IDs. If the
given ID is currently attached, it will be detached. Likewise, if it
is currently detached, it will be attached:
Example:
$problem->counselings()->toggle($counselingsToToggle);
I would change your store() method to something like this :
public function store(Request $request)
{
$counseling = Counseling::create([
'student_id' => $request->student_id,
'user_id' => Auth::user()->id
]);
if($request->has('problem_id'){
$counseling->problems()->attach($request->problem_id);
//return something if problem id is in request
}
//return something if problem id is not there
}
I want to get the notifiable model relation while getting notifications for a specific user. And plus I want to save and get custom morph relation (i.e. causer (causer_id and causer_type)) in notification table (just like notifiable). I was able to create a morph relation and saving it into table record but I am having trouble while getting the relation model, it returns null in both relations. Sharing the code.
custom DatabaseChannel -- the modified buildPayload method.
protected function buildPayload($notifiable, Notification $notification)
{
$data = $this->getData($notifiable, $notification);
$causer = $data['causer'];
unset($data['causer']);
return [
// README: removed uuid from here
'type' => method_exists($notification, 'databaseType')
? $notification->databaseType($notifiable)
: get_class($notification),
'data' => $data,
'read_at' => null,
'causer_type' => get_class($causer),
'causer_id' => $causer->id,
];
}
custom notifiable trait
use Illuminate\Notifications\Notifiable as BaseNotifiable;
trait Notifiable
{
use BaseNotifiable;
/**
* Get the entity's notifications.
*/
public function notifications(): MorphMany
{
return $this->morphMany(Notification::class, 'notifiable')
->orderBy('created_at', 'desc');
}
}
and one thing more I'd like to ask here, how can I refer to two morph relations to single table, like I want to add notifications method with causer and as well as notifiable.
custom Notifications Model
class Notification extends DatabaseNotification
{
public function causer()
{
return $this->morphTo();
}
}
what I am missing or doing wrong? Is it even possible what I am trying to do?
In order to get morph relation (one or maybe two), you need to select columns {morph}_id and {morph}_type, this is just in case if you are using ->select() while getting records, if you are not using select, that'd not be doing any issue.
EDIT
Here is how you add custom columns to notifications table
public function up()
{
Schema::table('notifications', function (Blueprint $table) {
$table->string("causer_type")->after('notifiable_id');
$table->unsignedInteger("causer_id")->after('causer_type');
$table->index(["causer_type", "causer_id"]);
});
}
public function down()
{
Schema::table('notifications', function (Blueprint $table) {
$table->dropMorphs('causer');
});
}
Okay I want to have custom field that does not exist as a column in my db table.
I followed, last part :
http://laravel.com/docs/4.2/eloquent#accessors-and-mutators
My model code:
class Car extends Eloquent{
protected $fillable = array('driverID', 'fuelRemaining');
protected $appends = array('is_driver');
public function user(){
return $this->belongsTo('user');
}
public function getIsDriverAttribute(){
return ($this->attributes['driverID'] == Auth::user()->id);
}
}
Car table:
Schema::create('cars', function(Blueprint $table)
{
$table->increments('id');
$table->integer('driverID');
$table->integer('fuelRemaining');
$table->mediumtext('desc');
$table->timestamps();
});
As you can see i want an extra field which is "is_driver" to be returned, but when I run this, this field is used to determine whether current signed in user is the driver himself by comparing the IDs.
it will output this error:
Undefined index: driverID
Not sure what am I doing wrong here, please advice.
Ah I have found why. This is a reference for future readers
In my controller I only get these two
$car = Car::where('fuelRemaining', 0)->get(array('id', 'desc'));
When i added authorID to the get array
$car = Car::where('fuelRemaining', 0)->get(array('id', 'desc', 'authorID'));
I am able to get the authorID attribute in my custom accessor mentioned in the question.
I have three tables staff, customer, service.
I have created pivot for customer and service as customer_service(has extra fields).
Now I want to link the staff to customer_service. So i tried to use customer_service as a model 'Custserv' and tried to relate with staff. It didnt workout.
Because I don't want staff linking directly to customer and service
I had this following relationship working
/*Model - Service*/
public function customer(){
return $this->belongsToMany('customer')->withPivot(
'start_date',
'stop_date',
'rem_date',
'due_date',
'status'
);
}
/*Model - customer*/
public function services(){
return $this->belongsToMany('Service')->withPivot(
'start_date',
'stop_date',
'rem_date',
'due_date',
'status'
);
}
////These following relations didnt workout
/*Model - custserv*/ //uses the pivot table customer_service//
public function staff(){
return $this->belongsToMany('Staff');
}
/*Model - Staff*/
public function custservs(){
return $this->belongsToMany('Custserv');
}
/*schema for pivot table 'staff' and 'Custserv' */
Schema::create('customer_service_user', function(Blueprint $table)
{
$table->increments('id');
$table->integer('customer_service_id')->unsigned()->index();
$table->foreign('customer_service_id')->references('id')->on('customer_service')->onDelete('cascade');
$table->integer('staff_id')->unsigned()->index();
$table->foreign('staff_id')->references('id')->on('staff')->onDelete('cascade');
$table->timestamps();
});
Then I tried ...
$staff = User::find(1)->custservs;
return $staff;
It gave error
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'auditCrm_db.custserv_user' doesn't exist (SQL: select `customer_service`.*, `custserv_user`.`user_id` as `pivot_user_id`, `custserv_user`.`custserv_id` as `pivot_custserv_id` from `customer_service` inner join `custserv_user` on `customer_service`.`id` = `custserv_user`.`custserv_id` where `custserv_user`.`user_id` = 1)
If my relationshiop is correct how to get and set values between Staff and Custserv?
You may have figured it out, but I think you are doing it overly complicated. When using a many-to-many relationship Laravel provides the pivot property. You already have withPivot in your relationship.
Now you can access it like that:
$staff = User::find(1)->services()->first()->pivot; // or you could loop over services
return $staff;
I have a customers migration table
Schema::create('customers', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('address');
$table->string('phone');
$table->string('email');
});
and a tripsheet migration table which goes like this
Schema::create('tripsheets', function(Blueprint $table) {
$table->increments('id');
$table->integer('tripsheet_num');
$table->integer('customer_id');
$table->string('date');
$table->string('customer_name');
$table->string('customer_address');
$table->string('customer_phone');
$table->string('rep_address');
$table->string('rep_phone');
});
I have also created a customer eloquent,
class Customer extends Eloquent {
public $timestamps = true;
public $table = 'customers';
protected $fillable = ['name', 'address', 'phone', 'email'];
public function tripsheets(){
return $this->belongsTo('Tripsheet', 'name', 'address', 'phone');
}
}
and a tripsheet model,
class Tripsheet extends Eloquent {
public $timestamps = true;
public $table = 'tripsheets';
protected $fillable = [];
public function customer(){
return $this->hasMany('Customer', 'name', 'address', 'phone');
}
}
and my routes.php goes like this,
Route::get('/', function()
{
return View::make('hello');
});
Route::controller('/customers', 'CustomerController');
Route::controller('/tripsheets', 'TripsheetController');
I would like to link the customer_name, customer_address, customer_phone from the tripsheet table to the name, address, phone of the customer table. I also want to know how to route them and fetch them as a json data to be used by angular JS to display the result.
now should i create a third table to link these two? Or should i call it with Customer::with('tripsheets')->all();in the routes/controller?
I also want to know how to route them and fetch them as a json data to be used by angular JS to display the result.?
I overlooked your code and after user315.. answer I see the problem. The belongsTo and hasMany has wrong arguments.
You need to change your code to the following to make it work:
class Customer extends Eloquent {
public function tripsheets(){
return $this->belongsTo('Tripsheet', 'tripsheet_num');
}
}
class Tripsheet extends Eloquent {
public function customer(){
return $this->hasMany('Customer', 'tripsheet_num');
}
}
The problem is that you have the field tripsheet_num in the table tripsheets. Laravel tries to find a field called tripsheet_id inside the tripsheets table when you use the belongsTo(Tripsheet) on Customer. In your case this key field is named different and is not found, and so the relation is not set.
Same goes for hasMany() only then it looks in the other table for the key field.
See the relation documentation for more info: One-to-one relation & hasMany
You only need the first argument in your belongsTo and hasMany method. The others are likely the reason why it's not working. They are meant for telling Eloquent what the foreign key is, and if you are specifying the foreign key as name, then it's obviously not going to work right.
Since you have proper naming conventions, Eloquent can accurately guess what they should be and you shouldn't need them.