I seen to of got tangled in Laravel's ORM with the following:
Scenerio: All Users have a Watchlist, the Watchlist contains other Users.
I can't seem the get the relationships to work correctly as they are cyclical, so far I have the following:
class UserWatchlist extends Model
{
protected $table = 'UserWatchlist';
public function Owner() {
return $this->belongsTo('App\User');
}
public function WatchedUsers() {
return $this->hasMany('App\User');
}
}
Schema::create('UserWatchlist', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('Users')->onDelete('cascade');
$table->integer('watched_id')->unsigned();
$table->foreign('watched_id')->references('id')->on('Users')->onDelete('cascade');
$table->timestamps();
});
class User extends Model
{
public function Watchlist() {
return $this->hasOne('App\UserWatchlist');
}
public function WatchedBy() {
return $this->belongsToMany('App\UserWatchlist');
}
}
It is not pulling through the correct in formation i'm expecting. Am I missing something fundamental?
Since UserWatchlist is a pivot table, i suppose you are facing a many to many relationship with both the elements of the relation being the same model (User)
If that is the case, you should not build a model for the pivot table UserWatchlist but all you have to do is to set the relation between the users through the pivot table:
class User extends Model
{
//get all the Users this user is watching
public function Watchlist()
{
return $this->belongsToMany('User', 'UserWatchlist', 'user_id', 'watched_id' );
}
//get all the Users this user is watched by
public function WatchedBy()
{
return $this->belongsToMany('User', 'UserWatchlist', 'watched_id', 'user_id' );
}
}
Check here for more info on many-to-many relationship
Related
Below are all of the models, migrations and controller.
Donation Model
class Donation extends Model
{
protected $guarded =[];
public function users(){
return $this->hasMany(User::class);
}
public function items(){
return $this->belongsTo(DonationItems::class);
}
}
Donation Items Model:
class DonationItems extends Model
{
protected $guarded=[];
public function donation(){
return $this->hasMany(Donaition::class);
}
}
Donation Items Migration:
public function up()
{
Schema::create('donation_items', function (Blueprint $table) {
$table->id();
$table->string('category');
$table->timestamps();
});
}
Donation Migration:
public function up()
{
Schema::create('donations', function (Blueprint $table) {
$table->id();
$table->string('item');
$table->unsignedInteger('user_id');
$table->unsignedInteger('donation_item_id');
$table->timestamps();
});
}
In my controller I want to access the items as follows:
$don = Donation::all();
$don->items;
But I'm unable to achieve this.
Its not working because laravel follows one rule for relationships:
Remember, Eloquent will automatically determine the proper foreign key column on the Comment model. By convention, Eloquent will take the "snake case" name of the owning model and suffix it with _id. So, for this example, Eloquent will assume the foreign key on the Comment model is post_id.
So you can try by supplying local and foreign id
So it would look something like this
Donation Model
class Donation extends Model
{
protected $guarded =[];
public function users(){
return $this->hasMany(User::class);
}
public function items(){
return $this->belongsTo(DonationItems::class, 'donation_item_id', 'id');
}
}
Donation Items Model:
class DonationItems extends Model
{
protected $guarded=[];
public function donation(){
return $this->hasMany(DonationItems::class, 'id', 'donation_item_id');
}
}
I am writing from my head you might need to swap local and foreign ID's
I want to return the projects of the authenticated user, but am not getting any. I know the records exist in the database.
This is my model Project:
public function users(){
return $this->hasMany(User::class);
}
this is my model User:
public function projects(){
return $this->hasMany(Projet::class,'user_id');
}
and this is the controller function :
public function projetuser(){
$user = User::find(auth()->user()->id);
return $user->projects;
}
and this my user_projet migration:
public function up()
{
Schema::create('user_projet', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('projet_id');
$table->foreign('projet_id')->references('id')->on('projets')->onDelete('cascade');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('membre')->nullbale();
$table->timestamps();
});
}
You are defining a many-to-many relationship incorrectly. Use belongsToMany() instead of hasMany(). Because your pivot table name is not standard (it should be alphabetic order projet_user) you need to include it in the relationship definition as well.
<?php
use Illuminate\Database\Eloquent\Model;
class Projet extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'user_projet');
}
}
class User extends Model
{
public function projets(){
return $this->belongsToMany(Projet::class, 'user_projet');
}
}
Now in your controller you can do this:
public function projetuser(){
return auth()->user->projets;
}
Your question seems to vary between "projet" and "project." I assumed "projet" was the correct spelling, but try to keep this consistent.
Please note also the typo in your migration: nullbale.
I have an app where Users can have multiple Books. I have set up the relation ship and the intermediary table. But the query is not working.
Book Model
public function user(){
return $this->belongsToMany('App\Book', 'book_user');
}
User Model
public function book(){
return $this->belongsToMany('App\User', 'book_user');
}
Create user_book table migration:
public function up()
{
Schema::create('book_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('book_id')->unsigned();
$table->foreign('book_id')->references('id')->on('books');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});
}
Books controller I add the book_id and user _id to the table
public function readlist(Book $book)
{
DB::table('book_user')->insert(
['user_id' => auth()->id(),
'book_id' => request('book_id')]
);
}
In my home controller I try to access the books related to a user but my results return Null;
public function index()
{
$user = Auth::user();
$userbooks =$user->books;
dd($userbooks);
return view('/home');
}
First rename you book() method to books() in your User model :)
Then you can try to do this:
public function readlist(Request $request)
{
Auth::user()
->books()
->attach($request->get('book_id'));
}
User have multiple Books,
Book have multiple Users,
The relationship is many to many,
It's better to define the User model:
public function users(){
return $this->belongsToMany('App\Book', 'book_user');
}
And in your Book model
public function books(){
return $this->belongsToMany('App\User', 'book_user');
}
The Doc Link: https://laravel.com/docs/5.7/eloquent-relationships#many-to-many
i have category_content, contents and users tables which each contents belong to many category_content and category_contentbelong to many contents and each contents belongs to one user and one user has many post on contents table
class Contents extends Model
{
...
public function categories()
{
return $this->belongsToMany(ContentCategories::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
class ContentCategories extends Model
{
...
public function contents()
{
return $this->belongsToMany(Contents::class);
}
}
class User extends Authenticatable
{
...
public function content()
{
return $this->hasMany(Contents::class);
}
}
by this below code i can find categories content that category id is 7
$nodejsContents = ContentCategories::find('7')->contents;
now, problem is here, how can i get post owner in this query which content is belongs to which user
i tested this code but i get error:
$nodejsContents = ContentCategories::find('7')->contents->user;
Error:
"Undefined property: Illuminate\Database\Eloquent\Builder::$contents"
contents_categories migration:
public function up()
{
Schema::create('contents_categories', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('lang',2)->default('fa');
$table->integer('parent')->default(0);
$table->timestamps();
});
}
user is within contents, so access with closure,
$nodejsContents = ContentCategories::has('contents')->with(['contents' => function($query){
$query->with('user')->get();
}])->find('7');
ContentCategories::find('7')->contents
belongsToMany Contents would return a collection. So you could either loop through the collection to get the related user of Contents
or
ContentCategories::find(7)->contents->with('user');
There is something I miss in the eloquent one-to-one relationship:
class MeetingTest extends Model
{
protected $table = 'meeting_tests';
public function meeting() {
return $this->belongsTo('App\Meeting','meeting_id','id');
}
public function observation() {
return $this->hasOne('App\Observation','meeting_test_id','id');
}
public function activity() {
return $this->hasOne('App\TestActivity','activity_id','id');
}
}
The Observation Class is
class Observation extends Model
{
protected $table = 'observations';
public function meetingTest() {
return $this->belongsTo('App\MeetingTest','meeting_test_id','id');
}
}
If I run php artisan tinker and
$mtn = App\MeetingTest::create();
$mtn->save();
$ob = App\Observation::create();
$ob->save;
$mtn->observation()->save($ob);
At this point inside the Observation record I can see the meeting_test_id filled with the correct id of the meetingTest, but if I try:
$mtn->observation
it gives me null; and in the Database there is no observation ID in the observation_id field;
this is the migration:
Schema::create('meeting_tests', function (Blueprint $table) {
$table->increments('id');
$table->integer('meeting_id')->unsigned();
$table->integer('observation_id')->unsigned()->nullable();
$table->integer('activity_id')->unsigned()->nullable();
$table->timestamps();
});
I don't understand what is not correct.
I can see observation_id and activity_id in your meeting_tests table, which makes records in this table the owned side of one-to-one/one-to-many relation. Therefore, both activity and observation relations in MeetingTest should return $this->belongsTo instead of $this->hasOne