in symfony we can access many-to-many relations with getter functions which return objects of ArrayCollection type.
for example for getting Alex's students we can call $alex->getStudens(), then i have access to ale's studens object.
now my question is how i can access alex's students id's in array, for example by calling $alex->getStudentsIds() it returns {1,5,7,12,..} , which are his students's ids.
precisely how you wrote it, you add another function in the entity
public function getStudentsIds()
{
$students = $this->students;
$studentIds = [];
foreach($students as $student)
{
$studentIds[] = $student->getId();
}
return $studentIds;
}
Ideal solution would be to add such a method to a repository and have it query only for student ids for given object but this is the simpliest solution possible.
Related
I'm trying to update/insert and sync several objects in a many to many relationship.
There is a many to many relationship between A and B entities.
I have an array with the list of ids of entity B that i would like to insert in entity A. The sync method will delete all the entities that aren't in the array.
If such method doesn't exist in Symfony, what is the symfony way to handle this situation??
Symfony does not have a function equivalent to SYNC.
A way to handle this is to add a public function to the entity A
public function sync($ids, array $array_bs){
//get all Bs
$bs = $this->getB();
foreach ($bs as $b){
$id = $b->getId();
if (strpos($id,$ids)== false){
//remove
$this->removeB($b);
}
//add new child entities
foreach ($array_bs $bs){
$this->addB($bs);
}
}
}
I'm trying to get the clan members of the primary tournament, with only a season instance.
I fetch the primary tournament using a query on the tournaments relationship, I then call the clans relationship on the tournament model I just fetched.
Except.. it isn't a model anymore, I'm pretty sure its a query? Or a collection, sorry for my lack of understanding but in a simple explanation, I can no longer access relationships?
I need help in how I can do this with still being able to call clans after querying the tournament.
Here are my models.
class Season extends Model
{
public function clans() {
return $this->belongsToMany(Clan::class);
}
public function tournaments() {
return $this->hasMany('App\Tournament', 'season_id');
}
public function primaryTournament() {
return $this->tournaments->where('is_primary', '1');
}
}
class Tournament extends Model
{
public function clans() {
return $this->belongsToMany(Clan::class);
}
public function season() {
return $this->belongsTo('App\Season', 'season_id');
}
}
I'm trying to achieve this:
$season = Season::all()->last();
$tournament = $season->primaryTournament();
$teams = $tournament->clans; // this is what erorrs
What's stopping me?
Property [clans] does not exist on this collection instance.
try
$teams = $tournament->clans(); // with parenthesis
The problem is apparently in $tournament, which is a collection of Tournament class, and not an instance of a unique one (because it's obtained by ->where('is_primary', '1')),
you can select the first instance by ->first() methode
or loop through $tournament values and access clan property.
Try this $teams = $tournament->clans();
Clans is relation function on your model, you need to put parentheses. This should return a collection of the Clan class.
How can I use Laravel Relations while using Query Builders ?
$Cars = User::find(1)->car; // works well and returns all cars
$User = User::where('username' , 'John')->get();
$Cars = $User->car; // doesn't work.
Any help.
thanks
Solved
$User = User::where('username' , 'John')->get();
Should Be
$User = User::where('username' , 'John')->first(); // to get an object instead of array
The ::find() method will return an instance of your model, which allows you to access relations and such that are setup on the model.
The ->get() method will return an Illuminate\Database\Eloquent\Collection of results, even if there is only 1 row selected from the database.
Using the collection you can then loop through the results
$collection->each(function($model)
{
// You can now access $model->cars
});
Alternativly you may use the ->first(), ->last() and ::find() methods to return a single instance of your model which allows you to directly access relations.
$model = Model::where('foo', 'bar')->first(); // Returns first row from the database
$model->cars // Is now accessable
Assuming you already have your Cars class all you have to do is to add method to your User class.
//add this method to your User class
public function cars()
{
//since you'll be using many to many
//you might use `user_cars` as pivotal table
return $this->belongsToMany('Cars', 'user_cars', 'cars', 'cars');
}
You may call it using:
User::find(1)->cars()->get();
For a school project, I'm creating a website in the Laravel framework.
I can't work with the data from a many-to-many table in my controller.
Here are my models:
class Item extends Eloquent {
public function Tags()
{
return $this->belongsToMany('Tag', 'items_has_tags', 'items_id', 'tags_id');
}
}
class Tag extends Eloquent {
public function LearningMaterials()
{
return $this->belongsToMany('LearningMaterial', 'learning_materials_has_tags', 'tags_id', 'learning_materials_id');
}
}
I want to iterate all tags from my items in my controller:
//get all items
$all = Item::where('public', '1')->get();
foreach($allLm as $item){
$tags = $item->Tags();
var_dump('will iterate');
foreach($tags as $t){
var_dump('will not iterate');
}
}
What is wrong with my code? How can I handle the tags from my items?
FYI: I'm creating a search engine. If the user inserts an input value like "mana", all items with tag "management" should be shown.
Laravel's belongsToMany method queries related models and doesn't get them. That's because you might want to have some additional constraints in your query. What you need to do is:
$tags = $item->Tags()->get();
Or simply:
$tags = $item->Tags;
Calling the relationship function will return a relation object (in this case an instance of BelongsToMany). You can use this to run add further components to your query before running it.
For example:
$only4Tags = $item->Tags()->take(4)->get();
If you want the result of your relation, call get() or simpler, just use the magic property:
$tags = $item->Tags()->get();
$tags = $item->Tags;
I'm using Eloquent to select a single row from a table called "businesses". Any business can be associated with one or more "Industries". I've set this up in the business model such that:
public function industries() {
return $this->belongsToMany('Industry');
}
In the controller I am eager loading the industries when I select the model:
$mdl = Business::find($business_id);
$mdl->load('industries');
return Response::json($mdl);
This returns something like this:
{"id":123,"name":"My Business","address":"123 Easy Street","industries":[{"id":1,"name":"Technology"},{"id":7,"name":"Research"}]}
This is almost what I need. I'm looking to just have the response look like this instead:
{"id":123,"name":"My Business","address":"123 Easy Street","industries":[1,7]}
I know I could just do something like this:
$ind = array();
foreach($mdl->industries as $industry) $ind[] = $industry->id;
$mdl->industries = $ind;
I'd rather not do that though. It's ugly and it makes my code look very non-laravel.
The reason I'd like to do it this way in the first place is because when I SAVE the business I am going to use something like this:
$mdl->industries()->sync(Input::get('industries'));
The SYNC method only accepts an array of IDs so I'd rather the JSON object going to and from the server have the same format. I'd really rather not an array of objects when I load it and an array of ids when I save. Is there a best practice for this sort of thing or an easier way to accomplish what I'm trying to do?
Thanks!
$mdl = Business::with('industries')->find($business_id)->toArray();
$mdl['industries'] = array_pluck($mdl['industries'], 'id');
return $mdl;
If you use this a lot, add the following method to your Business model:
public static function getWithIdustryIds ($business_id)
{
$mdl = Business::with('industries')->find($business_id)->toArray();
$mdl['industries'] = array_pluck($mdl['industries'], 'id');
return $mdl;
}
Your model relationship should be
public function industries() {
return $this->belongsToMany(Industry::class);
}
Assuming that your pivot table has an industry_id column you can eager load only the industry_ids using
$mdl = Business::with(['industries' => function($query){
$query->select('industry_id');
}])->get()