Laravel extending creation model - php

I'm trying to extend when the creation of a model happens.
The model called Competition that has the following function:
public function Team(){
return $this->belongsToMany('Team');
}
now on creation of an Competition, I want to add in a pivot table for every user in the team an value.
how can I do this?
I tried the following, but that doesn't work:
public function __construct($attributes = array()){
parent::__construct($attributes);
foreach($this->Team->Users as $user){
// insert some data in table
}
}
that would give me the following error when going to a page:
EDIT:
I figured out that this isn't the way to go, this get's called even when no objects are created, so I have to find the Create command for an model (not researched this yet)

I didn't had to do this in the __Construct();
I had to do this in create():
public static function create(array $attributes){
$var= parent::create($attributes);
// code
}

Related

How to pass parameter to a laravel elequent model's event observer

I have a model in laravel and I want to do something after the first time which an object of my model is created. the simplest way is to add a static boot method inside my model's class like the code below:
class modelName extends Model
{
public static function boot()
{
parent::boot();
self::created(function ($model) {
//the model created for the first time and saved
//do something
//code here
});
}
}
so far so good! the problem is: the ONLY parameter that created method accepts is the model object itself(according to the documentation) :
Each of these methods receives the model as their only argument.
https://laravel.com/docs/5.5/eloquent#events
I need more arguments to work with after model creation. how can I do that?
Or is there any other way to do something while it's guaranteed that the model has been created?
laravel version is 5.5.
You're close. What I would probably do would be to dispatch an event right after you actually create the model in your controller. Something like this.
class WhateverController
{
public function create()
{
$model = Whatever::create($request->all());
$anotherModel = Another::findOrFail($request->another_id);
if (!$model) {
// The model was not created.
return response()->json(null, 500);
}
event(new WhateverEvent($model, $anotherModel));
}
}
I solved the issue using static property in eloquent model class:
class modelName extends Model
{
public static $extraArguments;
public function __construct(array $attributes = [],$data = [])
{
parent::__construct($attributes);
self::$extraArguments = $data ;
public static function boot()
{
parent::boot();
self::created(function ($model) {
//the model created for the first time and saved
//do something
//code here
self::$extraArguments; // is available in here
});
}
}
It works! but I don't know if it may cause any other misbehavior in the application.
Using laravel events is also a better and cleaner way to do that in SOME cases.but the problem with event solution is you can't know if the model has been created for sure and it's time to call the event or it's still in creating status ( and not created status).

Model object load/access relation model in controller

Using laravel I have a method that I am posting to in my Controller:
public function hired(Quote $quote)
{
var_dump($quote->project);
exit;
$quote is created as a Model object but the above code returns NULL
I have the correct relationship setup:
public function project()
{
return $this->belongsTo(Project::class);
}
I understand that I need to "load" these relationship models onto the object but not sure how??
I thought that when I access ->project the relationship would be automatically loaded...
Thanks
Ensure that you maintain the same naming convention for the variable in your route and method arguments.
Example:
Route::post('quote/{quote_id}/hired', 'QuoteController#hired')->name('quote.hired');
Should then be in the controller:
public function hired(Quote $quote_id) {
Thanks to #scottevans93 for leading me to my mistake.

Laravel 5 Eager Loading not working

I look at many search results with this trouble but i can`t get it to work.
The User Model:
<?php namespace Module\Core\Models;
class User extends Model {
(...)
protected function Person() {
return $this->belongsTo( 'Module\Core\Models\Person', 'person_id' );
}
(...)
And the Person Model:
<?php namespace Module\Core\Models;
class Person extends Model {
(...)
protected function User(){
return $this->hasOne('Module\Core\Models\User', 'person_id');
}
(...)
Now, if i use User::find(1)->Person->first_name its work. I can get the Persons relations from the User Model.
But.. User::with('Person')->get() fails with a Call to undefined method Illuminate\Database\Query\Builder::Person()
What im doing wrong? i need a collection of all the users with their Person information.
You have to declare the relationship methods as public.
Why is that? Let's take a look at the with() method:
public static function with($relations)
{
if (is_string($relations)) $relations = func_get_args();
$instance = new static;
return $instance->newQuery()->with($relations);
}
Since the method is called from a static context it can't just call $this->Person(). Instead it creates a new instance of the model and creates a query builder instance and calls with on that and so on. In the end the relationship method has to be accessible from outside the model. That's why the visibility needs to be public.

Laravel get data from pivot table

I have a pivot table of users_operators.
I want to grab the operator_id of the user.
This is how i do this now, but its seems like verbose way.
if (Auth::user()->type === 'operator') {
$user = Auth::user();
// There is a better way to do this?
$operator_id = $user->operator[0]['pivot']['operator_id'];
Session::put('operatorId', $operator_id);
}
class Operator extends \Eloquent
{
public function users() {
return $this->belongsToMany('User');
}
}
class User extends \Eloquent
{
public function operator() {
return $this->belongsToMany('Operator');
}
}
I'm, battling insomnia and not functioning at 100%, but you should be able to get away with $user->operator->id based on what I'm interpreting your models to be (it looks like you had a typo when you copied them into the question).
If that doesn't work, you might want to check out the "Dynamic Properties" section in the Eloquent docs for more info, if you haven't already.

Acces Model-function from inside the model

I'm pretty new to Laravel and am struggeling with the following problem at the moment:
I want to create a User-Group-Management. So I want to add Users to a Group and add Rights to these Groups, to have an authorization. My aim is to have a User::hasRight('exampleRight') function, which i can easily call. For that I wanted to have a function chaining inside of the User-Class. I have this function to create a Connection to the UserGroup-Table (which connects an User-ID to a Group-ID):
public function role()
{
return $this->hasOne('UserGroup');
}
The next function shall return an Array of rights. My plan was to write something like
public function rights()
{
$rights = Groups::find($this->role()->groups_id)->rights;
return $rights;
}
The GroupsModel of course has this function to get the Rights:
public function rights()
{
return $this->hasMany('Rights');
}
But obviously $this->role()->groups_id doesn't give me the groups_id but instead throws the Error Undefined property: Illuminate\Database\Eloquent\Relations\HasOne::$groups_id. When i leave the ->groups_id out, and do add it instead in the controller like:
(Attention Controller, no model!)
public function getUserRole()
{
return User::find(10)->rights->groups_id;
}
it gives me the right answer. Can somebody tell me, whats the error? I don't really get whats wrong...
Thanks you in advance!
Regards
In this particular method you need to remove the parenthesis:
public function rights()
{
$rights = Groups::find($this->role->groups_id)->rights;
return $rights;
}
When you do role() you're actually telling Laravel to return the relation object, so you can do things like
$this->role()->where('x', '=', 'y')->get();
Why do you have an intermediary table between User and Group? Simply give the User a group_id. Here is how I have built this in the past.
User belongsTo Group
Group belongsToMany Right
// Inside User Model
public function can($name)
{
foreach ($this->group->rights as $right)
{
if ($right->name == $name)
{
return true;
}
}
return false;
}
// Elsewhere
if (!$user->can('edit_blogs'))
{
return 'FORBIDDEN';
}
Look into eager loading to mitigate performance issues.
Look into filters to apply these access restrictions at the controller or route level.

Categories