Trying to add data for my many to many relationship - php

I have a pivot table where I store Student and guardian relationships, I create student first before adding guardian Cause Student and guardian have two tables and I relate to them using ids. When I create a new Guardian everything works fine but the problem is when I try to merge an old guardian with a new student and I call my model "getStudent" i get the error "Call to a member function getStudent() on string"
//Guardians Model
public function getStudent()
{
return $this->belongsToMany(Student::class);
}
//Student Model
public function Guardians()
{
return $this->belongsToMany(Guardian::class);
}
//Controller
if (isset($_POST['merge'])) {
$student = Student::find($id);
$guardian = $req->input('parent_id');
dd($guardian->getStudent()->attach($student->id));
}
I am able to get the two Id but how do I save without errors to my pivot?

you are calling getStudent() function from a request Object you can call this function form a Guardian modal instance so
you code should look like
if (isset($_POST['merge'])) {
$student = Student::find($id);
$guardian = Guardian::find($req->input('parent_id'));
dd($guardian->getStudent()->attach($student->id));
}

You should do like this:
if (isset($_POST['merge'])) {
// $student = Student::find($id);
$guardian = Guardian::find($req->input('parent_id'));
$guardian->getStudent()->attach($id);
}

Related

Why belongsTo() return null?

I have two models and two tables. First model name Inbox with database structure:
And second model name is StudentData with database structure:
And I will return with route('/sended') all mesages using my method for get needed messages:
public function getMessages($message_type = "new")
{
$user_id = Auth::user()->id;
$inbox = new Inbox();
$paginate = 3;
switch ($message_type) {
case 'sended':
$messages = $inbox->where('sender', $user_id)
->where('trashed_in_sender', 0)
->where('show_in_sender', 0)
->orderBy('created_at', 'desc')
->paginate($paginate);
break;
default:
return abort(404);
break;
}
return $messages;
}
And I have methods in my model Inbox:
public function messageSender()
{
return $this->belongsTo("App\StudentData", 'sender');
}
public function messageRecipient()
{
return $this->belongsTo("App\StudentData", 'recipient');
}
When I call in view $message->messageSender in result given NULL. Why I can't get data using sender id from inboxes table in student_datas table
So, I have a few questions....
1) How exactly does your User and StudentData models interact? It kinda seems strange to have 2 models with what seems to be a 1:1 relationship?
Why not just use a User model?
(Do you even have a User model or am I misinterpreting things?)
2) I think your direction is wrong... if you already have a User model, try to get the sent messages from there. I will give you an example.
Let's say you have a User model and a Inbox model, where you have a "sender" and "recipient", which both have an id of the User model.
So in the Inbox model we have:
public function messageSender()
{
return $this->belongsTo("App\User", 'sender');
}
public function messageRecipient()
{
return $this->belongsTo("App\User", 'recipient');
}
But why not go from the other direction? We can write the relationships in the User model like
public function sentMessages()
{
return $this->hasMany("App\Inbox", 'sender');
}
public function receivedMessages()
{
return $this->hasMany("App\Inbox", 'recipient');
}
Now you can get all sent messages (i.e. all messages where the user is the sender) just by using
$user->sentMessages
and operate on that. Or you could even set up a special helper relation (my name sucks, find a better one... just for example)
public function unreadSentMessages()
{
return $this->hasMany("App\Inbox", 'sender')
->where('trashed_in_sender', 0)
->where('show_in_sender', 0)
->orderBy('created_at', 'desc');
}
and can either use $user->sentMessages for all his messages or $user->unreadSentMessages for only the ones you need in your case.

How to make a query when have array

I have three tables: client, project and client_project.
I want to show in a view all the projects of one client.
Here is the explained code:
<?php
public function editClient($id)
{
$client = Client::find($id);
// I get an array with client_id and project_id of the clients
// which is the same I pass in the URL.
$client_project = DB::table('client_project')->where('client_id',$id)->get();
// return view('cms.public.views.clients.editclient')->withClient($client);
}
Now I want to show the name of projects when the field id of table projects have the same value of project_id in $client_project array.
Here is the example of how to do it if it's only one value, maybe can help.
public function editClient($id)
{
$client = Client::find($id);
$client_project = DB::table('client_project')->where('client_id',$id)->first()->project_id;
$project = DB::table('projects')->where('id',$client_project)->first();
return $project;
}
Use One to Many relationship.
In Client.php Model
public function projects()
{
return $this->belongsTo('App\Project', 'client_id');
}
And in your Project.php Model
public function client()
{
return $this->hasMany('App\Client', 'client_id');
}
Now call
$client_project = Client::find($id)->projects;
You will get details here https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
Instead of taking the first() client project, take them all and use the whereIn() method in project selection.
$projects = DB::table('projects')->whereIn('id', function ($query) {
$query->select('project_id')->from('client_project')->where('client_id', $id);
})->get();
Here's the laravel documentation link: Laravel 5.5 Documentation - Queries#where-clauses
I'm answering on what I've understood about your request which is not very clear.

many to many attach() says trying to get property of non-object

I have two database tables journeys and stops that are related in a many-to-many relationship. There is also the third table journey_stop (the pivot table) for the relationship.
Models
Here is my Journey.php model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Journey extends Model
{
public function stops() {
return $this->belongsToMany('App\Stop');
}
}
and the Stop.php model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Stop extends Model
{
public function journeys(){
return $this->belongsToMany('App\Journey');
}
}
Controller
Now in my controller, I have written a method changeStop(stop, journey_id) which takes a particular journey_id and either assigns a stop to it.(that is, creates a relationship between that particular stop and the journey) or removes the stop from the journey if it already exists.
Here is the method:
public function changeStop(Request $request, $id)
{
$stop = $request->all();
$journey = Journey::find($id);
if ($journey->stops()->contains($stop->id)) {
$journey->stops()->detach($stop->id);
}else{
$journey->stops()->attach($stop->id);
}
return $journey->stops();
}
But the line with the if statement throws the error:
Trying to get property of non-object
I have also tried using DB to query the pivot table directly but it throws the same error. Here's the code with DB:
public function changeStop(Request $request, $id)
{
$stop = $request->all();
$journey = Journey::find($id);
if (
DB::table('journey_stop')->where(
'journey_id',
$id
)->where(
'stop_id',
$stop->id
)->count() > 0
) {
$journey->stops->detach($stop->id);
} else {
$journey->stops->attach($stop->id);
}
return $journey->stops();
}
Everything seems right for me. But it doesn't work. What am I doing wrong?
Thanks for your time :)
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. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table
$journey->stops()->sync([$stop_id])
And to work for your above code try this:
public function changeStop(Request $request, $id)
{
$stop = $request->all(); // returns an array
$journey = Journey::find($id);
if ($journey->stops->contains('id', $stop['id'])) {
$journey->stops()->detach($stop['id']);
} else {
$journey->stops()->attach($stop['id']);
}
return $journey->stops;
}

Get laravel data with relation between tables

I have the following data models:
class Cliente extends Model
{
public function sector()
{
return $this->belongsTo(Sector::class,'sectoresId');
}
}
class Sector extends Model
{
public function sectorLanguage()
{
return $this->hasMany(SectorLanguage::class,'sectoresId');
}
public function cliente()
{
return $this->hasMany(ClienteLanguage::class,'sectoresId');
}
}
class SectorLanguage extends Model
{
public function sector()
{
return $this->belongsTo(Sector::class,'sectoresId');
}
public function idioma()
{
return $this->belongsTo(Idioma::class,'idiomasId');
}
}
I want to recover all the active clients and the name of the sector to which it belongs, if I do something like this
$cliente = Cliente::where('active','1');
When I run $client I can not enter the attribute
foreach($cliente as $cli) {
$cli->sector->sectorLanguage->nombre;
}
Why? It only works for me when I find it by id
$cliente = Cliente::find(1);
echo $cliente->sector->sectorLanguage->nombre;
How can I get what I need without resorting to doing SQL with Query Builder.
Thank you very much, greetings.
According to your defined relations, the Sector has many sectorLanguage, it means you're receiving a collection, so you should work on an object like this:
$cliente->where('active', 1)
->first()
->sector
->sectorLanguage
->first()
->nombre;
Cliente::where('active', 1) and sectorLanguage gives you the collection, so you
should first get the first item from $cliente & sectorLanguage and then apply the
desired relationship
Hope it should work!

Trying to get the property of a non-object in laravel

I have two tables: user and student. The field username from user is a foreign key as login_id in student. I have created eloquent relationships in each model, but when I try to access Auth::user()->student->id it gives me:
Trying to get the property of a non-object.
Student Model:
public function user()
{
return $this->belongsTo('user','login_id');
}
User Model:
public function student(){
return $this->hasOne('student')
}
ProfileController.php
<?php
class ProfileController extends BaseController
{
public function showinfo()
{
if (Auth::check())
{
$user_id = Auth::user()->username;
$student_id = Auth::user()->student->id;
}
}
}
Above noted error occurs when I try to log in.
You should check first if the user who login has student, so i would suggest
$student = Auth::user()->student;
if($student) $student_id = $student->id;
$student_id = Auth::user()->student->id;
If it doesnt contain value, then you get that error. Try using isset, or empty, depends on what you like.
Only with many to many relations you use the ( ).
Example:
$user_companies = Auth::user()->companies();
foreach($user_companies as $company)

Categories