I have 3 tables Users, Profiles, and Friends.
Users contains users, obviously.
Then I got the Profiles and Friends table (see below).
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('picture')->nullable();
$table->string('status')->nullable();
$table->string('text')->nullable();
$table->boolean('show_sex');
$table->boolean('show_dob');
$table->timestamps();
});
}
public function up()
{
Schema::create('friends', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id_sender')->unsigned();
$table->integer('user_id_receiver')->unsigned();
$table->foreign('user_id_sender')->references('id')->on('users');
$table->foreign('user_id_receiver')->references('id')->on('users');
$table->integer('status'); // 1 = friends, 2 = under validation
$table->timestamps();
});
}
As you can see, i created some foreign keys that relates to the Users table.
The Friends table contains all friendships between users (the status field will determine if the friendship is under validation or validated).
I have the default User model that comes with Laravel 5.2 and was wondering, how can I easely get all the friendships, that belongs to the signed user?
Could I use something like belongsTo() or something to easely get all friendrequests where the user_id_receiver field is the same as the signed users id? I didn't quiet understand the documentation for hasOne or belongsTo.. Would be nice if someone could clearify how it actually works.
Thanks in advance.
Yes, you should use One-to-one relation between User and Profile models and One-to-many relation between User and Friend models. Add this to both models - Friend and Profile:
public function user()
{
return $this->belongsTo('app\User');
}
And add this to User model:
public function profile()
{
return $this->hasOne('app\Profile');
}
public function friend()
{
return $this->hasMany('app\Friend');
}
And then you could use Eloquent to get data:
$signedUserId = Auth::user()->id;
$currentUserFriendRequests = Friend::where('user_id_receiver', $signedUserId)->get();
I hope this will be helpful.
Related
I have a Many To Many relationship between users & wallets.
So at the User.php Model:
public function wallets()
{
return $this->belongsToMany(Wallet::class,'user_wallet','user_id','wallet_id')->withPivot('balance');
}
And at Wallet.php Model:
public function users()
{
return $this->belongsToMany(User::class,'user_wallet','user_id','wallet_id');
}
And also the table Migration of user_wallet also goes here:
public function up()
{
Schema::create('user_wallet', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('usr_id')->on('users');
$table->unsignedBigInteger('wallet_id');
$table->foreign('wallet_id')->references('id')->on('wallets');
$table->integer('balance');
$table->timestamps();
});
}
Now I need to return a data based on it's User Id & Wallet Id, like this:
And at the Controller:
$bal = Wallet::where(['user_id' => $user_id, 'wallet_id' => $wallet_id]);
But this is wrong because the Model Wallet is connected to wallets table and not the pivot table which is user_wallet.
So how can I define user_wallet table for this where condition?
I would really appreciate any idea or suggestion from you guys about this...
Thanks in advance.
I think you can use whereHas
Wallet::with("users")->whereHas('users',function ($query)use($user_id){
$query->where('user_id',$user_id);
})->find($wallet_id)
or
Wallet::with("users")->whereHas('users',function ($query)use($user_id,$wallet_id){
$query->where('user_id',$user_id);
$query->where('wallet_id',$wallet_id);
})->first()
And also relationship need to be updated in wallet model
public function users() {
return $this->belongsToMany(User::class,'user_wallet','wallet_id','user_id');
}
I don't understand how to return info back to blade template if I have two related tables:
First table is standard Laravel 'users' table
Second table:
Schema::create('recipes', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('code', 10);
$table->string('description');
$table->float('size');
$table->bigInteger('created_by')->unsigned();
$table->string('status')->default('pending');
$table->boolean('deleted');
$table->timestamps();
$table->foreign('created_by')
->references('id')
->on('users')
->onDelete('cascade');
}
Than I have two Controllers: User and Recipe
Recipe have
public function user()
{
return $this->belongsTo(\App\User::class);
}
and User have
public function recipes()
{
return $this->hasMany(\App\Recipe::class);
}
actual output looks like this (RecipesController):
$recipes = Recipe::latest()->paginate($perPage);
return view('admin.recipes.index', compact('recipes'));
everything looks OK but column created_by contain users primary key witch is integer. How can I display users name? This is something like inner join but is it possible to do that in eloquent? Or I completely misunderstanding those public functions in a Model?
Your user relationship in your Recipe model is missing the foreignKey:
public function user()
{
return $this->belongsTo(\App\User::class, 'created_by');
}
You can then eager load the users with your recipes in the controller:
$recipes = Recipe::with('user')->latest()->paginate($perPage);
return view('admin.recipes.index', compact('recipes'));
And finally you can access the user in the view:
#foreach($recipes as $recipe)
{{ $recipe->user->name }}
#endforeach
You can read more about the inverse of the one-to-many relationship in the docs.
I need to make a relationship between User and Subscription table.
The user who registers gets a default free user and sees 1 an offer.
If silver see 8 offers, gold 15, platinum 20.
I made a relationship between user and subscription tables with a pivot table subscription_user.
The first question is whether I made a mistake somewhere in relation the model?
The second question is how to return only one offers by default, or if you subscribe to 8 offers (silver), 15 (gold), 20 (platinum) and in which controller?
User table:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('subscription')->default('free');
$table->rememberToken();
$table->timestamps();
});
Subscription table:
Schema::create('subscriptions', function (Blueprint $table) {
$table->increments('id');
$table->string('subscription');
$table->integer('offers');
$table->timestamps();
});
Sabscription_user table:
Schema::create('subscription_users', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index(); //user table
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); //foreign key relation
$table->integer('subscription_id')->unsigned()->index();
$table->foreign('subscription_id')->references('id')->on('subscriptions')->onDelete('cascade'); //foreign key relation
});
Subscription model:
class Subscription extends Model
{
public function users() {
return $this->belongsToMany('App\User');
}
}
User model:
public function subscriptions(){
return $this->belongsToMany('App\Subscription');
}
Is everything connected as it should be for many to many relationship?
In which controller I can get information about offers?
By convention the pivot table is named singular so you will need to specify by adding a second argument. I like to include all the arguments so there is no guessing anyway.
public function subscriptions()
{
return $this->belongsToMany("App\Subscription", 'subscription_users', 'user_id', 'subscription_id', 'id', 'id');
}
public function users()
{
return $this->belongsToMany("App\User", 'subscription_users', 'subscription_id', 'user_id', 'id', 'id');
}
Yes you should use a controller but it depends on where you are trying to display this. I imagine you will need to display the current subscriptions somewhere as well as add and remove.
I need to seed a relationship in Laravel, where each user has many devices
The User model
public function devices()
{
return $this->hasMany(Device::class);
}
The Device model
public function users()
{
return $this->belongsTo(User::class);
}
}
The device_user table
Schema::create('device_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('device_id')->unsigned()->index();
$table->foreign('device_id')->references('id')->on('devices')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
The seeder
factory(App\Device::class, 20)->create()->each(function(App\Device $device) {
$device->users()->attach([
rand(1,5),
rand(6,15),
rand(16,20),
]);
});
But, when I run the migration with seeder, I get this message
Call to undefined method Illuminate\Database\Query\Builder::attach()
Please, help
attach for many to many relationships, you don't need device_user table for one to many relationship, in one to many you should create a column with name user_id in device table and just it. after that you can insert data in device table with user_id. and get user relationship with
Device::user()->get();
I am using Auth::user() to get information on the current logged in user. Now I want to extend the Information delivered by Auth::user(). Concrete the activation state of the user shall be available.
This information is stored in the table activations in the column state.
From my understanding Auth::user() delivers what will be retrived from the user model. So I should create a relationship between table users and table activations. The documentation states 2 posibilites, both require that the activations table has a foreign_key user_id.
My table layout does not cover that, I just have refernce in the users table to the actvtion_id.
is there a possibilty to build a relationsship with my table layout, which leads to the desired result, that Auth::user() deliveres me the activation state? If how should I do it?
Or do I have to switch the table layout as recommended in the documentation?
Below my table code:
Controller:
class ProfileController extends Controller {
public function me()
{
return Auth::user( );
}
}
users (migration):
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('email')->unique();
$table->integer('activation_id')->unsigned();
$table->foreign('activation_id')->references( 'id' )->on( 'activations' );
//...
$table->timestamps();
});
activations (migration):
Schema::create('activations', function(Blueprint $table)
{
$table->increments('id');
$table->string('activationStatus', 1)->nullable()->default('N');
// ...
$table->timestamps();
});
Firstly, you need to define a model relationship in your User model:
public function activation()
{
return $this->belongsTo('App\Activations', 'activation_id');
}
Now, you can easily lazy load the Activation relationship from the authenticated user:
$user = Auth::user()->load('activation');
If you want to get the activation status, you can now do:
var_dump($user->activation->activationStatus); // Prints 'Y' / 'N'