Have researched extensively eloquent relationships and laravel all afternoon and can't seem to find a solution.
I have a transaction table displaying User IDs in the From and To columns. I want to show the users emails that correspond to their IDs.
Here is my relationships:
Transaction model:
public function user()
{
return $this->belongsTo('App\User', 'id', 'email');
}
User model:
public function transaction()
{
return $this->hasMany(App\Transaction);
}
And heres the code from the controller. However I KNOW this just returns ALL the transactions. But I really can't find how I would display the emails instead of the IDs:
public function index()
{
$table = Table::create(Transaction::get());
return view('table', compact('table'));
}
Maybe you should try to get transactions with related model (user) or with join to users table?
$transactions = Transaction::query()->with(['user'])->get();
$table = Table::create(Transaction::get());
$table->addColumn('email', 'E-mail', function($model) {
return $model->user->email;
});
return view('table', compact('table'));
Related
I've got a problem since several days in Laravel.
My database is like attached picture.database
User<->Role many-to-many-relationship works correctly.
In addition, I would like to add another many-to-many relationship in role_user pivot table. So I did:
user.php:
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function role_users()
{
return $this->hasMany(RoleUser::class);
}
role.php:
public function users()
{
return $this->belongsToMany(User::class);
}
public function role_users()
{
return $this->hasMany(RoleUser::class);
}
And pivot roleUser.php:
public function user()
{
return $this->belongsTo(User::class);
}
public function role()
{
return $this->belongsTo(Role::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
When I populate tables, I can get data: relations work.
Now I want to save data and let Laravel to populate tables automatically. At this moment and time, I save roles data in users.php with:
$this->Roles()->sync($roles);
($roles is an json array data from a form request..).
Pivot table get the user_id and role_id. Ok, cool.
Now, what should I write to get role_user_id and tag_id in role_user pivot table when I add a roles?
Thank you in advance!
I think you should use
$this->Roles()->attach($roles);
Rather than
$this->Roles()->sync($roles);
Because if I'm not wrong, sync will remove the pivot data. And you should pass the primary_key and foreign_key to your belongsToMany function. If you wanted to add data to the pivot column in your pivot table, try to add ->withPivot('column name');
Database
I'm kind of new to databases and I made this small database, but I have problems fetching data from it.
Im trying to get all the racers from the logged in user, and it works properly, but if I enter $pigeons = $user->racer I only get back the racer table. I would like to know the attributes of the racers from the pigeons table aswell. I've made it work with query builder left joining the tables but I'm not sure why I set up this relationship if I can't use Laravel inner method.
In the User model I have these relationships:
public function pigeons(){
return $this->hasMany('App\Pigeon');
}
public function racers(){
return $this->hasManyThrough('App\Racer', 'App\Pigeon');
}
This is the Pigeon model:
public function user(){
return $this->belongsTo('App\User');
}
public function racer(){
return $this->hasMany('App\Racer');
}
}
And this is the Event model:
public function race(){
return $this->hasOne('App\Race');
}
public function racers(){
return $this->hasMany('App\Racer');
}
And this is what my EventsController looks like with the working alternative method and the commented not working.
public function upcoming(){
$id = auth()->user()->id;
$user = User::find($id);
$pigeons = DB::table('racers')->leftJoin('pigeons', 'racers.pigeon_id', '=', 'pigeons.id')->where('pigeons.user_id', '=', $id)->get();
//$pigeons = $user->racers;
return view('events.upcoming')->with('pigeons', $pigeons);
}
This is what I get with $user->racers or $user->racers()->get():
[{"id":1,"pigeon_id":14,"user_id":4,"event_id":1,"position":0,"created_at":null,"updated_at":null},{"id":2,"pigeon_id":15,"user_id":4,"event_id":1,"position":0,"created_at":null,"updated_at":null},{"id":3,"pigeon_id":16,"user_id":4,"event_id":1,"position":0,"created_at":null,"updated_at":null}]
And this is what I want to get, its not correct either since I should get id:1 but I want to pass to view these additional datas aswell like gender, color, ability (but they are in pigeons table not in racers).
[{"id":14,"pigeon_id":14,"user_id":4,"event_id":1,"position":0,"created_at":"2018-09-27 10:01:04","updated_at":"2018-09-27
10:01:04","gender":"hen","color":"blue","ability":38},{"id":15,"pigeon_id":15,"user_id":4,"event_id":1,"position":0,"created_at":"2018-09-27 10:01:04","updated_at":"2018-09-27
10:01:04","gender":"hen","color":"blue","ability":48},{"id":16,"pigeon_id":16,"user_id":4,"event_id":1,"position":0,"created_at":"2018-09-27 10:01:04","updated_at":"2018-09-27
10:01:04","gender":"cock","color":"blue","ability":11}]
To get the pigeons, what you would have to do is $pigeons = $user->racers()->get();. You can see an example of this in Laravel's official documentation https://laravel.com/docs/5.5/eloquent-relationships#introduction.
Laravel 5.5
I've got two models, User and Conversation
User to Conversations is a many to many relationship (both ways).
My table structure is as follows:
conversation is on database_1
conversation_user is on database_1
user is on database_2
Inside App\Conversation.php:
protected $connection = 'database_1';
protected $table = 'conversations';
public function users()
{
return $this->belongsToMany("App\User");
}
Inside App\User.php:
protected $connection = 'database_2';
protected $table = 'users';
public function conversations()
{
return $this->belongsToMany("App\Conversation");
}
All of this is on the same server but is there a way to have this working or not ?
When querying the relationship on Conversation to get users, it's looking for database_2.conversation_user instead of database_1.conversation_user
So in essence, I need to say that the Pivot table is located in database_1, is there a way to do this?
One way to work around this is using the query builder to create the relationship. In your User model try:
public function conversations()
{
return DB::connection('db1_connection_name')->table('conversation_user')->where('user_id', $this->id)->get();
}
Apparently you can prefix the connection in a relationship also:
public function conversations() {
return $this->belongsToMany(User::class, env('DB_CONNECTION_1').'.conversation_user', 'user_id', 'conversation_id');
}
In laravel I'm connecting events to users like this:
class User extends Model
{
public function events()
{
return $this->belongsToMany('App\Event', EventUser::TABLE_NAME, 'user_id', 'event_id');
}
}
which works great, but now I'm implementing repeat feature so I'm inserting repeating events for 2 years in the future in the database, and I don't want to make 1000 inserts, so I decided that I'll have parent event, and subevents will have parent_id in the database. Now the problem is that I can't get those events with belongsToMany, since I need to watch for 2 keys... id and parent_id.
Any idea how I can do that? I want to get events connected with user and events that have parent event connected with user.
public function parentEvents()
{
return $this->belongsToMany('App\Event', EventUser::TABLE_NAME, 'user_id', 'event_id');
}
public function childEvents()
{
return $this->belongsToMany('App\Event', EventUser::TABLE_NAME, 'user_id', 'parent_id');
}
public function events()
{
$parentEvents = $this->parentEvents;
$childEvent = $this->childEvents;
// Merge collections and return single collection.
return $parentEvents->merge($childEvents);
}
I'm just getting started with Laravel so please forgive any noobness.
I have a User and Order model, a user has many orders:
# Inside User model
public function orders()
{
$this->hasMany('Order');
}
# Inside Order
public function user()
{
return $this->belongsTo('User');
}
// Not sure if this is upsetting anything (also in Order)
public function products()
{
return $this->belongsToMany('Product');
}
So I think I have the above right.
But when I do this:
$users = User::with('orders')->find(1);
return $users;
I get Call to a member function addEagerConstraints() on null.
However, if I do it the other way around, it works great:
$orders = Order::with('User')->get();
return $orders;
What am I doing wrong / what don't I understand?! Or is my problem bigger than I think?
Database:
The problem is you don't have return for your orders relationship. It should be:
public function orders(){
return $this->hasMany('Order');
}
You should also use your relationships case sensitive. you showed:
$orders = Order::with('User')->get();
is working, but you should rather use
$orders = Order::with('user')->get();
to avoid extra queries to your database in future
For anyone else that runs across this, I was having the same issue, but my problem was that I had the foreign/local keys swapped. Example:
// This is correct for hasX relationships
public function user() {
return $this->hasOne('App\Models\User', 'user_id', 'local_key_user_id');
}
// This is correct for belongsTo relationships
public function user() {
return $this->belongsTo('App\Models\User', 'local_key_user_id', 'user_id');
}
Notice that for hasX relationships, the foreign key is the second parameter, and the local key is the third. However, for belongsTo relationships, these two are swapped.
Probably doesn't answer this particular question but it relates to the title. I had the same issue here is the wrong query
$offer = Offer::with([
'images:name,id,offer_id',
'offer_options:offer_option,value,id,offer_id',
'user:id,name,avatar'])
->select(['id', 'views', 'type', 'status'])
->where('id', $id)->get();
the model look like this
class Offer extends Model {
function user(): BelongsTo {
return $this->belongsTo(User::class);
}
}
The User
class User extends ..... {
function offer(): HasMany {
return $this->hasMany(Offer::class);
}
}
The issue with the query is I was not selecting user_id, i.e in my select function user_id column was not included and that is why I was getting null for user
according to Laravel docs
When using this feature, you should always include the id column and
any relevant foreign key columns in the list of columns you wish to
retrieve.
So the correct query is
$offer = Offer::with([
'images:name,id,offer_id',
'offer_options:offer_option,value,id,offer_id',
'user:id,name,avatar'])
->select(['id', 'views', 'type', 'status','user_id'])
->where('id', $id)->get();