Laravel Foreign Key 'Trying to get property of non-object' - eloquent

I simply cannot wrap my head around Models.
I have two tables, users and companies. Users contains a column called Company which is a foreign key to the companies table. the companies table has two columns, an ID and company_name The value of Company under users references the id in Companies.
I am trying to get the value of company_name through the foreign key like so.
$user = User::find(1)->company->company_name;
My thought process, which may be wrong, is that this (depending on if models are correct) should get the value of the Company column and then using that value, get the company_name from the Companies table.
My models look like so
User
public function company() {
return $this->belongsTo('App\Company', 'company');
}
Company
protected $table = 'companies';
public function user() {
return $this->hasOne('App\User');
}
All I continuously get is Trying to get property of non-object
I can see in the error log it gives that it's actually getting the company name too!
Trying to get property of non-object', 'C:\wamp\www\laravel\app\Http\Controllers\HomeController.php', '41', array('userid' => '1', 'usercompany' => '1', 'company' => 'BMW'))
But I don't understand where it's pullyig userid and usercompany from.
What am I doing wrong?

In this case, you're trying to get the property of a non-object, meaning that either User::find(1) or company is not an object. In the error message provided, it looks like one of the two is an array.
Look at your underlying database tables. Generally, the id is a protected field that is not returned in the result object. usercompany looks like the concatenated field to cross-reference the two tables (i.e. the foreign key).

Related

Eloquent primary key default value null on model save

I am using UUIDs as my primary key in laravel.
The UUID is not generated by eloquent but by a default value in postgresql.
The default value is uuid_generate_v1mc(). This function is from the uuid-ossp package. The id is correctly generated.
But now the problem.
For example, I am creating an user:
$user = User::create(['email' => 'adsf', 'name' => 'adsf', 'password' => 'adf'])
This returns an user model without an id. I've found that I had to do an fresh() on the model to get the default values. But when I do this I get null. I think this is because the fresh function needs the id. But doesn't have it.
The user model has public $incrementing = false;. So that is setup correctly.
How can I get the full user model(In a clean way) when I create it? For the user the email is unique, so I could get the user based on the name. But for other tables this might not work.

retrieve full data from foreign table with eloquent

I've been reading some answers to similar questions here on the site, it seems everyone is trying to use a low level approach. The question is, shouldn't laravel and eloquent make it easy to solve stuff like that?
If I have a table with ids to two foreign tables, exmple item_id foreign of table items and item_type_id foreign of table item_types. How can I retrieve and join the data from these two tables directly instead of manually specifiying the id to look at in those foreign table and stuff?
Shouldn't eloquent have something like "get data from foreign table given the ids that you found in pivot table and spit out the joined data" ?
Laravel Eloquent: Relationships
I believe you should refer eloquent relationships. It would help you to fetch datas from related datatables.
For Ex: We can have 2 to 3 three table Users, Groups & user_group(pivot table)
The user_group would have the relation between each user and various groups.
In User Model
class User extends Eloquent
{
public function groups()
{
return $this->belongsToMany('Group', 'user_group', 'user_id', 'group_id');
}
}
In Group Model
class Group extends Eloquent
{
public function users()
{
return $this->belongsToMany('Group', 'user_group', 'group_id', 'user_id');
}
}
Now you can fetch a user and his relation with groups likewise:
$user_groups = User::find($user_id)->groups;
And to fetch the members of a group likewise:
$group_members = Group::find($group_id)->users;
This code basically does the join in the backend.
Refer docs for deeper understanding.
Hope this would get you started.

How to map a navigational property to a table where it isn't a key column?

I have an Entity like:
User
Id
Username
public virtual List<String> CountryNames { get;set; }
And it has a property for CountryNames as seen above, and this is linked to another table but it isn't linked on a key column.
The CountryNames property should get all UserCountry rows that have the Username.
UserCountry
Id
CountrName
Username
How can I configure the User model to do this?
I realize this is bad design, I'm not looking for schema design advise at this point as it is out of my hands.
I'm using EF6.

Extend User authentication object in Azure Mobile Services

Is it possible to add additional properties to the User object on the server in WAMS? I would like to store the Id primary key of my User table for (secure) use in my table scripts. At the moment the only id is the vendor specific authentication Id, but I'd like to be able to allow users to choose an authentication method. Currently my (simplified) table design is as follows:
User table:
id
googleId
twitterId
facebookId
name, etc...
League table
id
userId
name, etc
I'd like to store the user primary key in the userId field on the league table, and then query it to ensure that users only get to see leagues they created. At the moment, the user object in table scripts sends through a User object with the Google/Twitter/Windows authentication token and I have to do a query to get the primary key userID, everytime I want to carry out an operation on a table with a userId column.
Ideal solution would be that when the Insert script on my User table is called on registrations and logins I can do:
// PSEUDO CODE
function insert(item, user, request) {
var appUserId;
Query the user table using the user.userId Google/Twitter/Facebook id
If user exists {
// Set a persisted appUserId to use in all subsequent table scripts.
user.appUserId = results.id;
} else {
Set the GooTwitFace columns on the user table, from user.userId
insert the user then get the inserted record id
// Set a persisted appUserId to use in all subsequent table scripts
user.appUserId = insertUserPK;
}
}
Then, in subsequent table scripts, I'd like to use user.appUserId in queries
If all you are trying to do is authorize users to only have access to their own data, I'm not sure you even need the "user" table. Just use the provider-specific userId on the user object to query your "league" table (making sure the userId column is indexed). The values will be provider-specific, but that shouldn't make any difference.
If you are trying to maintain a notion of a single user identity across the user's Google/Facebook/Twitter logins, that's a more complicated problem where you would need a "user" table and the kind of lookup you are describing. We hope to ship support for this scenario as a feature out of the box. It is possible (but fairly messy) to do this yourself, let me know if that's what you're trying to do.

entity framework: how to assign foreign key in a entity

Here is my tables structure..
Profile: ProfileID (PK), ProfileName varchar(50), GenderID (Fk)
Gender: GenderID (PK), GenderName varchar(50)
Gender table has 2 possible values : Male, Female.
In entity framework, when I am updating the profile with GenderID, I use the following code:
profile.GenderID = Repository.
GetGender(
Request.Form["Profile.GenderName"].ToString()
).GenderID;
Repository.Save();
GetGender method looks like the following:
public Gender GetGender(string genderName)
{
return (from gender in db.Genders
where (gender.GenderName.Equals(genderName))
select gender).First();
}
Is there a better way of doing it? I feel like I am not using Entity Framework like it should be...
If I assign the value to profile.Gender.GenderID as opposed to profile.GenderID then I am updating the original Gender Lookup table which is not what I want.
I am confused..
Thanks..
If the only thing you have to look up the gender is the text description, then that's the best you're going to do (although I would probably add StringComparison.OrdinalIgnoreCase to the Equals). If you have the PK, there are other options.
It seems like a lot of effort to keep calling the database for this information. Could you not retrieve the pairs of values once, for example in Application_Start, put it in Cache, and then reference it as needed? After all, the values are not likely to change very often.