I'm using Laravel and I have a problem creating a team with a coach's id using eloquent expressions. I have users (basic users who can become coaches), then I have coaches who can have only one team and lastly teams, which can have 1 or 2 coaches. Their tables:
Users:
id | email | password | coach_id (null is default)
Coaches:
id | user_id | ... (other unnecessary coach info)
Teams:
id | coach_id | ... (other unnecessary team info)
I tried creating a team in TeamController's method (following laravel tutorial on Youtube https://youtu.be/z-1bdYTNWm8?t=6m50s):
$team = new Team();
$team->team_name = $team_name;
$team->organization = $organization;
$team->address = $address;
$request->user()->coach()->team()->save($team);
My user model:
public function coach(){
return $this->hasOne('App\Coach');
}
My coach model:
public function user(){
return $this->belongsTo('App\User');
}
public function team(){
return $this->hasOne('App\Team');
}
My team model:
public function coach(){
return $this->belongsToMany('App\Coach');
}
But i get this error:
BadMethodCallException in Builder.php line 2450:
Call to undefined method Illuminate\Database\Query\Builder::team()
You can try it as:
$team = new Team();
$team->team_name = $team_name;
$team->organization = $organization;
$team->address = $address;
$request->user()->coach->team()->save($team);
Note - Remove the () from coachrelation.
Update
When you add parenthesis () it creates the query builder and you don't have any relation named team in User model, so Laravel throws the error.
But when you do $request->user()->coach it returns the object of Coach model and then you can query it by the relation name team.
Related
So, I have a legacy Database, with a poorly designed structure that has recently been moved to Laravel, but with some hacky nonsense to get it to work with models. Given the following Tables:
|==========================|====|============|===========|
| companies | id | token | name |
|--------------------------|----|------------|-----------|
| people_{companies.token} | id | first_name | last_name |
|==========================|====|============|===========|
The companies table contains multiple records, with an auto-incrementing ID, unique token, and name.
Each Company has its own people_{companies.token} table, instead of a single people table, with an associated client_id.
At first, this meant I couldn't use a standard Company and Person Model/Relationships, as protected $table needs to be static. We got around this with a DynamicBinding Trait:
<?php
namespace App\Models\Traits;
trait DynamicBinding {
protected $connection = null;
protected $table = null;
public function bind(string $connection, string $table) {
$this->setConnection($connection);
$this->setTable($table);
}
public function newInstance($attributes = [], $exists = false) {
$model = parent::newInstance($attributes, $exists);
$model->setTable($this->table);
return $model;
}
}
This allows for setting a table on the fly:
$company = Company::first();
$people = (new Person())->setTable("people_{$company->token}");
$person = $people->first();
This works perfectly fine, returning the first record from the people_{$company->token} table, and facilitating most functionality required. Now, I'd like to make this work with Relationships. Given the following example:
// Person.php
public function company() {
return $this->belongsTo(Company::class);
}
$company = Company::first();
$people = (new Person())->setTable("people_{$company->token}");
$person = $people->first(); // No Issue
$peopleWithCompany = $people->with('company')->first(); // Cannot find table `people`
This returns the error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'database.people' doesn't exist (SQL: select * from people limit 1)
Essentially, as soon as ->with() (or other functions, like ->query(), etc) is appended, it tries to perform the query based on the determined table (people from Person) instead of the table set via $people->setTable().
Does anyone have any experience connecting models to this kind of data structure, while allowing use of Eager Loading with Relationships? And sidenote, there is a plan to migrate everything to a single people table, but unfortunately not anytime soon...
Thanks in advance!
im trying to create a one to one relationship with the table user,student and teacher. The problem is, when i run LARAVEL TINKER, app\user::find('a123')->teacher it displays the b345 data and doesnt display NULL. New in Laravel. Thanks
Below is the table with their PK.
User table
user_id | type
a123 | 1
b345 | 2
Student table
student_id| name
a123 | Danny
Teacher table
teacher_id| name
b345 | Mr.Mark
and this BELOW is the models.
User Model
protected $primaryKey = 'user_id';
public function student(){
return $this->hasOne(student::class,'student_id');
}
public function teacher(){
return $this->hasOne(teacher::class,'teacher_id');
}
Student Model (Teacher model is just the same with teacher_id as PK)
protected $primaryKey = 'student_id';
public function User()
{
return $this->belongsTo(User::class,'user_id');
}
From you description, student should belongs to user, also teach
In User Model
public function student(){
return $this->hasMany(Student::class,'student_id');
}
In Student Model
public function user(){
return $this->belongsTo(User::class,'student_id');
}
I'm trying to figure out how I can do a query within a query. (if that even makes sense) I want to grab all the activities. For each activity I want to get the count of users that did the activity. Then I want to order all the activities in DESC order based on the amount of users that did each activity. I'm basically making a "Popular Activities Page" where I show the all activities starting with the activity done by the most users.
I have 3 main tables for this
users
| id | name | password | email | created_at |
activities
| id | title | description | created_at |
resource This is a table I'm using for posts which shows which user did which activity. (Users can show what activities they did, and attach media and locations to the post)
| id | user_id | activity_id | media_id | location_id | created_at |
Here are my models for each table
User Model
class User extends Eloquent {
protected $table = 'users';
/**
* get the activities associated with the given user
* #return mixed
*/
public function activities()
{
return $this->belongsToMany('Acme\Activities\Activity', 'resource', 'activity_id');
}
public function posts(){
return $this->hasMany('Acme\Resource\Resource');
}
public function media()
{
return $this->hasMany('Acme\Media\Media');
}
public function locations()
{
return $this->hasMany('Acme\Locations\Location');
}
}
Activity Model
class Activity extends Eloquent {
protected $table = 'activities';
public function posts(){
return $this->hasMany('Acme\Resource\Resource', 'resource_id');
}
/**
* get the users associated with the given activity card
* #return mixed
*/
public function users()
{
return $this->belongsToMany('Acme\Users\User', 'resource', 'user_id');
}
}
Resource Model
class Resource extends Eloquent {
protected $table = 'resource';
public function user()
{
return $this->belongsTo('Acme\Users\User', 'user_id');
}
public function activities()
{
return $this->belongsTo('Acme\Activities\Activity', 'activity_id');
}
public function media()
{
return $this->hasMany('Acme\Media\Media', 'media_id');
}
public function locations()
{
return $this->belongsTo('Acme\Locations\Location', 'location_id');
}
}
I know I can get all activities using
Activity::get()
I can get a user count for a specific activity using
User::whereHas('resource', function($q) use ($activity_id){
$q->where('activity_id', $activity_id);
})->get()->count();
but I don't know how I can put all of this together in order to get all Activities sorted by user count, starting with the activity with the highest user count.
How would I make this query using eloquent?
Thanks in advance!
try
Resource::select(DB::raw('*, COUNT(distinct(user_id)) as user_count'))->group_by('activity_id')->order_by('user_count', 'desc')->get();
You could then do this
$results = Resource::select(DB::raw('*, COUNT(distinct(user_id)) as user_count'))->group_by('activity_id')->order_by('user_count', 'desc')->get();
foreach ($results as $result) {
$activity = Activity::where('id','=',$result->activity_id)->first();
// do stuff to display data for this activity like
// $activity->title or $activity->description
$count = $result->user_count;
}
I am making user to user messaging system in laravel 4. So in a simplified version i have to table
First table
Users
user_id |
user_name
Second table
Messages
message_id |
message_from_user_id |
message_to_user_id |
message_content |
So after reading the documentation I learned that User has many message and message belongs to User.
But how do I actually relate them in coding?
I am quite confused how will I use the foreign key in this case for a message that will have two user?
Check this out: http://laravel.com/docs/eloquent#many-to-many
Basically you need a table structure like this
Users: id | username
Messages: id | from | content
user_messages: user_id | message_id
You can define your models like this
class User extends Eloquent {
public function messages()
{
return $this->belongsToMany('Message');
}
public function sent_messages()
{
return $this->hasMany('Messages', 'from');
}
}
class Message extends Eloquent {
public function from()
{
return $this->belongsTo('User', 'from');
}
public function to()
{
return $this->belongsToMany('User');
}
}
Im really new to laravel, and im sure im doing something wrong
I have 2 tables. Cities And users_metadata
My cities table look like this
id | City |
1 | New York |
1 | Los Angeles |
users metadata
user_id | firt name | last name | cities_id |
1 | Jonh | Doe | 2 |
So my problem is when i create a relation i get New York, becaus the city id is matched with the user id
City model
class City extends Eloquent
{
public static $table = "cities";
public function profile()
{
return static::has_many('Profile');
}
}
profile model
class Profile extends Eloquent
{
public static $timestamps = false;
public static $table = "users_metadata";
public static $key = "user_id";
public function city()
{
return static::has_one('City');
}
}
error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'profile_id' in 'where clause'
SQL: SELECT * FROM `cities` WHERE `profile_id` = ? LIMIT 1
Bindings: array (
0 => 1,
)
If i dont pass the id to has one i get the following error
Okay i understand this.
So my questions is am i able to pass the foreign key cities_id somehow in my relation to match? Or im doing it all wrong? Can someone give me a basic example?
thank you folks
Try this:
City model
class City extends Eloquent
{
public static $table = "cities";
public function profile()
}
Profile model
class Profile extends Eloquent
{
public static $timestamps = false;
public static $table = "users_metadata";
public static $key = "user_id";
public function city()
{
return static::belongs_to('City');
}
}
I ran into the same problem thinking I should use has_one, but I needed to use belongs_to. user1808639's probably didn't work because you still had a 'has_many' in the city model.
Try this:
class Profile extends Eloquent
{
public function city()
{
return $this->belongs_to('City'); // city_id in the table
}
}
Laravel has a way of detecting foreign keys automatically. So for your database schema... this models should work fine
Try the following
user_id | firt name | last name | city_id | //city not cities
1 | Jonh | Doe | 2 |
-
class Profile extends Eloquent
{
public static $timestamps = false;
public static $table = "users_metadata";
public function city()
{
return $this->has_one('City');
}
}
/
class City extends Eloquent
{
public static $timestamps = false;
public function profiles()
{
return $this->has_many('Profile');
}
}
The table rows shouldn't contain whitespaces. So rename "firt name" | "last name" in "firstname" | "lastname". The SQL-error shows me that you're calling the model in the reverse way like City::find(1) in this case Laravel expects inside the "Cities" table the foreign key for the profiles that would be usually "profile_id".
I guess you're looking for something like this:
$user_id = 1;
$user = Profile::find($user_id);
echo $user->firstname." ".$user->lastname." lives in ".$user->city->city;