where is a model's attribute defined? - php

When I do $user = \App\Models\User::findOrFail(512) in php artisan tinker I get something like this back:
=> App\Models\User {#4586
userID: 512,
userName: "neubert",
legalFirst: "Neu",
firstName: "Neu",
lastName: "Bert",
...
}
Notably, has_ability_to_view_users_timeclock_reports is not present in what's returned. And yet when I do $user->has_ability_to_view_users_timeclock_reports I got a non-null value back (I get true back).
My question is... how might I found out where has_ability_to_view_users_timeclock_reports is defined? It's not defined in the App\Models\User model. When I do grep -r has_ability_to_view_users_timeclock_reports . in the code base I see it being used but never actually defined.
It's not a column in the table that \App\Models\User corresponds to.
Any ideas?

The output for models in tinker is determined here https://github.com/laravel/tinker/blob/97357b4ebec94d728847bff80362a4eb9f64ede0/src/TinkerCaster.php#L103
You can dd() your model to see more info

Related

Laravel object values don't exist, but then do if json_encoded

There's something weird going on in my Laravel query.
So I'm getting a collection of Users - if I run it through json_encode, all its keys/values are there. If I don't, some of them are null. E.g:
Log::info(json_encode($user)); // 'tasks_from_columns' exists
Log::info($user->tasks_from_columns); // null
Log::info($user->email); // exists?
Log::info(get_object_vars($user)); // 'incrementing', 'exists', 'wasRecentlyCreated', 'timestamps'
There's a relation on the User called tasks_from_columns. It's there if I json_encode it, but null if I try to access it directly. Most other keys are accessible though, like email, id etc.
If I run it through get_object_vars, none of them are shown. Just some other ones shown above.
Anyone know what the deal is?
The query itself is
$teamWithTasks = Team::where('id',$team->id)->with(['users' => function($query) use($team){
$query->with(['tasksFromColumns' => function($secondQuery) use($team){
$secondQuery->where('created_at','>',Carbon::now()->subDays(365))->with('project')->whereHas('project', function($thirdQuery) use ($team){
$thirdQuery->where('account_id', $team->account_id);
});
}]);
}])->first();

Use collection->get() instead of collection->pluck()

I am using laravel-permission for managing roles and displaying content. Per the docs you can retrieve a users roles by using $roles = $user->roles()->pluck('name'). My problem is that the data returned is ["admin"] rather than just admin. I was reviewing the collections methods and it looked like get('name') would return what I was looking for. When I try to use the following command Auth::user()->roles()->get('name') I get
1/1
ErrorException in BelongsToMany.php line 360:
Argument 1 passed to Illuminate\Database\Eloquent\Relations\BelongsToMany::getSelectColumns() must be of the type array, string given
It seems to me like the get() method is expecting an array however, I'm trying to reference an item in the array. The raw output of Auth::user()->roles()->get() is [{"id":1,"name":"admin","created_at":"2016-03-10 06:24:47","updated_at":"2016-03-10 06:24:47","pivot":{"user_id":1,"role_id":1}}]
I have found a workaround for pulling the correct content, but it is using regex for removing the unwanted characters that are included in the pluck() method.
preg_replace('/\W/i','', Auth::user()->roles()->pluck('name'))
It seems like I'm missing something or approaching using the get() method incorrectly. Any advice is appreciated.
I think pluck() will return the value of the given column for each model in the collection, which would explain the array. In your case it looks like the user has only one role, so you get an array with only one item. If the user had multiple roles, you would likely get an array with multiple items in it.
On the other hand, the get() method is used to execute a query against the database after a query is built. The results of the query are what is returned. To return a collection of models with only a single value you will need to pass an array with just the one column you want, but that will just select models, which does not appear to be what you ultimately need.
You can try this instead: $roles = $user->roles()->first()->name
The call to first() will grab the first model in the collection returned by roles(), and then you can grab the name of the role from that model.
I typically throw some error checking around this:
$role = $user->roles()->first();
if (is_null($role)) {
//Handle what happens if no role comes back
}
$role_name = $role->name;
That's because an user can have many roles, so roles is a collection.
If you are 100% sure that a user will have only one role, you can easily do
Auth::user()->roles()->first()->name
That will get the first item of that collection (the role) and then its name.

Laravel 5: Trying to get property of non-object error with relationships

Im running the latest version of Laravel.
I am trying to set up relationships with tables but I seem to always get some sort of error. The data that I want to be displayed is displayed but then under everything there is a big error saying:
ErrorException in routes.php line 26:
Trying to get property of non-object
In my routes.php file this is the code:
Route::get('select', function() {
$users = App\UserInfo::all();
foreach ($users as $u) {
echo $u->userID.' USERNAME: '.$u->userData->username.'<br/>';
echo $u->userOption->dis_joindate.'<br/>'; // Line 26
}
});
Line 25 seems to work fine printing no errors, though the next line gives the object error.
This is my UserInfo Model php file:
And this is my Options Model php file:
All that my database supplies (in the useroptions table) is and id, userID, dis_joindate, dis_location, dis_posts and dis_likes. And the last 4 colums just give text.
This is the image of the output on the page when all this is ran:
The problem here (assuming relationship are defined well) might be data. You might not have related data for each object.
So instead of:
foreach ($users as $u) {
echo $u->userID.' USERNAME: '.$u->userData->username.'<br/>';
echo $u->userOption->dis_joindate.'<br/>'; // Line 26
}
you should rather use:
foreach ($users as $u) {
echo $u->userID.' USERNAME: '.(($u->userData) ? $u->userData->username : '-').'<br/>';
echo (($u->userOption) ? $u->userOption->dis_joindate : '-').'<br/>'; // Line 26
}
In addition to lower number of queries instead of:
$users = App\UserInfo::all();
you should use eager loading like so:
$users = App\UserInfo::with('userData', 'userOption')->get();
Your userOption relationship isn't setup quite right. Because of this, the relationship will (unexpectedly to you) return null when the related record isn't found, and you'll get this error when you attempt to access dis_joindate on the null object.
In the comments you mention that you do have a useroptions record with a userID of 27, however that is not the record that is being loaded. The way your relationship is setup, it is actually looking for a useroptions record with an id of 27 (not userID).
When defining a belongsTo relationship, the second parameter is the name of the foreign key field on the Model which has the belongsTo relationship. In this case, when you specify userID, you're specifying userinfo.userID. The third parameter is the name of the field on the related Model on which to join. If not specified, it defaults to the primary key (usually id). Since you have not specified this parameter, it will default to useroptions.id.
If you would like relate records where userinfo.userID = useroptions.userID, you need to add the name of the related field to your relationship:
public function userOption() {
return $this->belongsTo('\App\Options', 'userID', 'userID');
}
You didn't mention the structure of the userData table, but you may want to check that out, as well.
you have a problem with relaitions in userOptions, it should have at least one record for every user.
in this case user 27 have no recorde in table userOptions and it its value is null and you try to use a property of null object

Twig and Symfony2 - Entity was not found

I have an entity that is related to some other entities.
On the end, I have an object like tat:
paper.submission.authors
For some of the paper.submission, there is no author, and in my twig template, I am doing:
{% for author in paper.submission.authors}
do something
{% endfor %}
And for the paper.submission with no authors, I am getting "Entity was not found" exception.
Is thee any possibility to test if the object exists before my for loop.
I have try the is defined, it is always true. Then, I have tryed is not null, but this is also generating the exception.
Thank you very much in advance.
Problem
Doctrine throws this Exception when it doesn't find the related entity. It seems redundant to say this, but in fact this is important.
It means it could find an ID related to it, but the request doctrine made didn't match any result.
My guess is that your database table (link table actually) submission.authors contains IDs of 0 instead of NULL.
With such, Doctrine thinks there IS an author with ID of 0, and therefor, cannot find it.
What happens
submission.authors always exists. It is an Uninitialized Doctrine Proxy.
var_dump($submission->getAuthors());
Would show you what contains exactly submission.authors
At this point, no queries are made. It simply returns a PersistentCollection with a flag isInitialized to false.
The exception occurs when you're trying to get a property out of it
foreach ($submission->getAuthors() as $author) {
}
When doing this doctrine will check if getAuthors is initialized. If not, it will run the following query
SELECT <stuffs> FROM authors WHERE id = 0;
Which returns no match and will throw an EntityNotFound Exception
Fix
You must set your id row's default to NULL and make a query to update all 0's to NULL.
With this, you can easily test submission.authors with is not null
Doctrine will not run any query if it finds a NULL
How to debug to find which related entity was not found?
Exception message improved in repository https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Proxy/ProxyFactory.php#L160 but if you use older version you can do the following debugging.
If you use older version
Put following code to ProxyFactory class before throw new EntityNotFoundException(); line vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php:177
$entity = $classMetadata->getReflectionClass()->getShortName();
$id = $classMetadata->getIdentifierValues($proxy)['id'];
var_dump("$entity WHERE id = $id NOT FOUND.");exit;
throw new EntityNotFoundException();
In your entity you can made something like this:
public function getSubmission(){
if($this->Submission->getId()==0) return null;
return $this->Submission;
}

Doctrine Error "Invalid expression found"

I have a table defined by:
Modification:
columns:
id:
type: integer
primary: true
autoincrement: true
name: string
author: string
attributes:
export: all
When I run this code:
$tbl = new Doctrine_Table(
'Modifications',
Doctrine_Manager::getInstance()
->getCurrentConnection()
);
$tbl->findOneBy('name', 'yacoby');
I get this error:
Doctrine_Table_Exception: Invalid expression found: ()n()a()m()e()
/home/yacoby/documents/dev/netbeans/php/Doctrine/Table.php:2741
/home/yacoby/documents/dev/netbeans/php/Doctrine/Table.php:1707
/home/yacoby/documents/dev/netbeans/ESSearch/test/library/Search/Table/ModsTest.php:21
Does anyone have any idea why and what I can do to fix it?
Try deleting the 's' after "Modification"...
If that doesn't have any affect, you may want to check that the table has been constructed properly by calling something like the method Doctrine_Table::getColumns and checking the output (i.e. that the array contains the columns you defined).
If it isn't what you expect, check that the files that the models are defined in have been loaded properly.
If the table has been set up already somehow, the correct way to get it is like this:
$tbl = Doctrine::getTable($what);
I ran into the same error while trying to construct (while I should have been getting) the Doctrine_Table of the $what entity to run som magic find functions on it.

Categories