I have the following 2 models in a morphToMany relationship: Company and Tag
public function tags(){
return $this->morphToMany(Tag::class, 'taggable');
}
public function companies(){
return $this->morphedByMany(Company::class, 'taggable');
}
and I have the following working action to save 1 tag to 1 company:
public function addTag($request){
$company = Company::find($request->company_id);
$company->tags()->syncWithoutDetaching($request->tag_id);
return response()->json($company->tags, 201);
}
now I'm trying to do the same thing with many companies and many tags and it is not working. I've tried "syncWithoutDetaching", "saveMany", passing in an array of integers or strings, I keep getting this error:
BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::tags does not exist. in file /home/vagrant/.../vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php on line 100
This is the function I am using:
public function multiCompanyAddTags($request){
$tags = $this->createManyRecords('App\AppSections\CRM\Models\Tag', $request->new_tags);
$tagIDs = $tags->map(function ($item, $key) { return $item->id;
});
foreach ($request->companies as $key=>$id)
{
$company = Company::with(['notes','tags','contacts','tasks'])->find($id);
$company->tags()->syncWithoutDetaching($tagIDs);
return response()->json($company, 201);
}
}
Someone pointed me to the answer: When calling $company = Company::with... in my loop, the call returns a collection and not the company.
I then need to call the first item of the collection to access the company, like so:
$company[0]->tags()->syncWithoutDetaching($tagIDs);
Related
I want to get a relation, here is my code:
OrderController.php
public function orders()
{
$orders = Order::with('packages')->OrderBy('created_at', 'DESC')->paginate();
return view('admin/orders/orders')->with(compact('orders'));
}
Order.php
function packages(){
return $this->hasMany('App\Models\Package', 'id','cart_items');
}
but the problem is cart_items contains a value like this (5,6) comma separated, how can I get relation hasMany from array?
Its's not possible by ORM need to work with mutator and accessor. Please remove packages method and try this in your Order model;
protected $appends = ['packages'];
public function getPackagesAttribute ()
{
if ($this->cart_items) {
$cart_items = explode(',', $this->cart_items);
if(count($cart_items)>0) {
return Package::whereIn('id', $cart_items)->get();
}
} return null;
}
I have this controller and I would like to return each person's furniture. This 'chilren' method didn't work. The relationship between the two 'one to many' is working correctly. It isn't mandatory to use children method. Any resource to solve the problem is accetable.
IMPORTANT: Laravel Version 5.8
PersonController.php
public function showPersonFurnitures($id) {
$person = Person::findOrFail($id);
$furnituresOfEachPerson = $person->childs();
return response()->json($furnituresOfEachPerson);
}
you are not triggering the query :
use this (with eager loading)
public function showPersonFurnitures($id) {
$person = Person::with('childs')->findOrFail($id);
$furnituresOfEachPerson = $person->childs;
return response()->json($furnituresOfEachPerson);
}
or this : (calling the relationship directly)
public function showPersonFurnitures($id) {
$person = Person::findOrFail($id);
$furnituresOfEachPerson = $person->childs()->get();
return response()->json($furnituresOfEachPerson);
}
or third option if the person->childs() relationship is a belongsTo :
public function showPersonFurnitures($id) {
$furnituresOfEachPerson = Child::where('person_id', $id)->get();
return response()->json($furnituresOfEachPerson);
}
I have a model file "Student" that contains the relation :
public function implementations()
{
return $this->hasMany(Implementation::class);
}
In my Implementation model, I have theses relations :
public function score()
{
return $this->belongsTo(Score::class, 'id', 'implementation_id');
}
public function project()
{
return $this->belongsTo(Project::class);
}
I would like to retrieve a table with all its data.
I tried this
public function getStudents($id)
{
$event = Event::where('id', $id)->first();
$data = $event->students()->with('implementations')->get();
return response()->json($data);
}
It works. But I do not have the result I would like. I would also like to recover the implementations data with theproject and score relationships
I tried that but it does not work
public function getStudents($id)
{
$event = Event::where('id', $id)->first();
$data = $event->students()->with('implementations')->with('project', 'score')->get();
return response()->json($data);
}
Thank you very much for your help!
Have you tried Event::with('students', 'students.implementations') yet? You can eager load relations of relations using the dot notation.
Hello I'm trying get my objects on laravel like this.
But I'm getting this error.
PHP error: Undefined property: Illuminate\Database\Eloquent\Collection::$retails on line 18
Also this is my code.
public function index(){
$retails = Auth::user()->companies->retails->all();
return view('retails/retails', compact('retails'));
}
Company Model
class Company extends Model
{
public function retails(){
$this->hasMany(Retail::class);
}
}
Retail Model
class Retail extends Model
{
public function company(){
return $this->belongsTo(Company::class);
}
}
You have many companies. That is why you get a collection from
Auth::user()->companies
When you call ->retails from the collection instance, you get the exception you wrote.
You have to eager load the companies with retails and then loop through them.
Like:
$u = auth()->user();
$u->load('companies.retails');
$userRetails = [];
$u->companies->each(function($company) use (&$userRetails) {
$userRetails = array_merge($userRetails, $company->retails->toArray());
});
$userRetails = collect($userRetails);
return view('retails/retails', compact('userRetails'));
According to your code, you're trying to access collection from a collection which is impossible, you should individually fetch a collection first and do your process
public function index(){
$companies = Auth::user()->companies;
foreach($companies as $company) {
$retails_arr[] = $company->retails;
}
$retails = collect($retails_arr); // Gives Collection or
// Or if you want to send array, try this
$retails = $retails_arr; // Gives Array
return view('retails/retails', compact('retails'));
}
Try this out hope this helps..
In my Menu controller I have a method which should display the specified record and all its children.
I have two models: MenuItem and MenuVariation, My items will have many variations as outlined in my methods:
MenuItem model
public function variant()
{
return $this->hasMany('App\MenuVariation');
}
MenuVariation model
public function item()
{
return $this->belongsTo('App\MenuItem', 'menu_item_id');
}
Now in my controller I have the following method:
public function show($id)
{
$item = MenuItem::findOrFail($id);
return $item;
}
...which currently only shows the item record but not its variations, so I have changed the code like this...
public function show($id)
{
$item = MenuItem::findOrFail($id)->with('variant')->get();
return $item;
}
but this oddly return ALL items and their variations.
Could someone help me get this working as desired? I would like to still utilise FindOrFail on the Item record, but it should also retrieve any variants (if found).
findOrFail will initiate the query, so you want to switch the order and put with in-front of it. Then use findOrFail. See Below:
public function show($id)
{
$item = MenuItem::with('variant')->findOrFail($id);
return $item;
}
There is also no need for get when you do that.