I'm try to get relations via laravel Eloquement model. I'm have two models ex Books.php and Magazine.php
in Books.php i have
public function magazines()
{
return $this->hasMany('App\BOOKS', 'id', 'id');
}
Then i'm try to return all magazines, which relate with books
$books = Book::find(123);
$magazines = $books->magazines()->get();
return $magazines;
but i'm have NULL magazines! When i'm add
$magazines = $books->magazines()->toSql();
i'm see this select: select * from "MAGAZINE" where "MAGAZINE"."ID" is null and "MAGAZINE"."ID" is not null - what is it? Why laravel model put "is null and is not null"?
Notice, if i'm change
public function magazines()
{
return $this->belongsToo('App\BOOKS', 'id', 'id');
}
Select would be like this: select * from "MAGAZINE" where "MAGAZINE"."ID" is null
Anyone know, what is this?
There are several problems in your code:
HasMany takes as first parameter the related model class so in your case is pointless to pass App\Book. You should pass App\Magazine assuming that your magazine model is called Magazine
you are not saying to the HasMany relationship what is the name of the foreign key on your magazines table.
That should do the job
public function magazines()
{
return $this->hasMany('App\Magazine', 'book_id', 'id');
}
IMHO i suggest you to read the Laravel documentation before posting here, there are a lot of examples that will explain to you how to work with relationships and database tables. Take a look to One to Many relationships.
EDIT
You can omit the ->get() on the relationship and simply fetch your magazines doing
$magazines = $books->magazines;
You should try this:
Please change and try:
public function magazines()
{
return $this->hasMany('App\MAGAZINE');
}
Related
I am struggling with an eloquent request. Let me explain what I want to do:
I have two models: User and Item
One User can have many Item and one Item belongs to One user.
I wrote the two method for this relation in my models as followed:
class Item extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
}
class User extends Model {
public function items() {
return $this->hasMany(Item::class, 'items', 'user_id', 'user_people_id');
}
}
I try to access to the items from my controller its user's relation with:
public function index()
{
$items = Item::with('user')->get();
dd($items);
FYI: I seeded my items table with 10 items and my user table with 4 users:
items table:
users table:
My problem is that in the when I check my query with dd() here is what I get: Only the 4 first items get the relation, the others 6 return a null value
Relation working:
Relation returning null:
Thank you for helping me!
According to Laravel doc, hasMany relationship parameters are the following:
return $this->hasMany(Myclass::class, 'foreign_key', 'local_key');
So try to change your relationship in your User class like that
// change this
return $this->hasMany(Item::class, 'items', 'user_id', 'user_people_id');
// to this
return $this->hasMany(Item::class, 'user_people_id', 'id');
The easiest solution would be to rename your foreign key to user_id. That is what Laravel expects, so you won't need to deal with extra arguments in your hasMany() functions.
If you can't do that I think this'll work: return $this->hasMany(Item::class, 'user_people_id');.
Please try to add all in your query to see if it will work:
Update
public function index()
{
$items = Item::all();
dd($items);
}
I have Task model. My Task model has some relationships and it currently looks like this:
class Task extends Model
{
use HasFactory;
public $timestamps = false;
public function city()
{
return $this->hasOne(City::class, 'id', 'city_id');
}
public function type()
{
return $this->hasOne(Type::class, 'id', 'type_id');
}
public function note()
{
return $this->hasOne(Note::class, 'id', 'note_id');
}
public function operator()
{
return $this->hasOne(User::class, 'id', 'operator_id');
}
}
Now, in my TasksController I need to get Tasks that match certain criteria, like this:
$tasks = Task::whereCityId($city->id)->whereTypeId($type->id)->get()->toArray();
The problem is that fields named city_id type_id note_id operator_id will get my integer values that they have.
Instead I would like to get certain value from a related Model.
For example:
operator_id should be replaced with username from User table that corresponds to the user id.
An obvious solution to this would be to simply use foreach loop, go through my results and get the data I need and simply create another array with the information replaced, but I am not sure if this is the best idea and perhaps there is something better.
You have to change in your code:
$this->hasOne(ClassName::class, 'id', 'foreign_key');
To
$this->belongsTo(ClassName::class, 'foreign_key', 'id');
because Task's id does not available as foreign key in these tables. These table's id present in task table as foreign key so you have to use belongsTo() relationship to tell script from where these id belongs.
Then access properties like this:
$tasks = Task::with("type", "city", "operator")
->whereCityId($city->id)->whereTypeId($type->id)->get();
foreach($tasks as $task){
echo $task->city->name;
}
first you should fix your relation:
public function city()
{
return $this->hasOne(City::class,'city_id','id');
}
and so one the same error, foreign key in argument order comes before the primary key.
after that you can use addSelect:
$tasks = Task::whereCityId($city->id)->whereTypeId($type->id)
->addSelect(['userName' => User::select('name')
->whereColumn('users.id', 'tasks.operator_id')
->limit(1)])->get()->toArray();
i think this will help better than what you ask.
$tasks = Task::whereCityId($city->id)
->whereTypeId($type->id)
->with('operator')
->get()->toArray();
with('operator') is ORM feature that make you collection to include its relation as collection property. In this case it will convert to array property.
you could access it from your foreach function as
#foreach($task as $key)
$key['operator']['username']
#endforeach
Have a nice day
I need to get all appeals, that have appeal_stage.expiration_date less than NOW().
Now I have following solution:
public function scopeExpired($query) {
$query->join('appeal_stage', 'appeals.id', 'appeal_stage.appeal_id')
->where('appeal_stage.expiration_date', '<=', new Expression('NOW()'));
}
but resulted model dump shows that joined table is recognized as pivot table:
So, I want to ask - Is there some more convenient way to perform this request?
My suggestions is use Illuminate\Database\Eloquent\Relations\Pivot somehow, bu I do not quiet understand, how Pivot can be used here.
UPD 1
Models has next relations:
public function stages()
{
return $this->belongsToMany(Stage::class)->withPivot('prolongated_count', 'expiration_date')->withTimestamps();
}
public function appeals() {
return $this->belongsToMany(Appeal::class);
}
You should be able to do something like this:
$appeal->stages()->wherePivot('expiration_date', '<', $now)->get()
You should create relationship in appeal model
public function stages()
{
return $this->belongsToMany(Stage::class,'appeal_stage','appeal_id','stage_id')->wherePivot('expiration_date','<',Carbon::now())->withTimestamps();
}
In belongs To Many relationship second argument is your Pivot table name
I have 3 tables in my database :
users (id);
interests (id);
users_interests (user_id, interests_id);
I want to be able to fetch all the user's interests in this way :
$interests = $user->interests
This is what I wrote in the User.php model, following laravel's doc:
public function interests() {
return $this->hasManyThrough(
'App\Interest', 'App\UserInterest',
'user_id', 'id', 'interest_id'
);
}
but it returns empty even though the user has a game. So there has to be something I'm doing wrong
Anyone to help me ?
I think a belongs to many would do the job:
public function interests() {
return $this->belongsToMany(
'App\Interest',
'users_interests',
'user_id',
'interests_id'
);
}
Quite similar to the example in the docs
If you were to rename users_interests table to interest_user and the column
interests_id to the singular form you would just need the first parameter:
public function interests() {
return $this->belongsToMany(App\Interest::class);
}
From my understanding the hasManyThrough is used to jump forward within a relation (also described in the docs):
The "has-many-through" relationship provides a convenient shortcut for
accessing distant relations via an intermediate relation.
I have the following schema set up:
users:
id
departments:
id
department_user:
id
department_id
user_id
I also have the following relationships set up:
User Model
public function departments()
{
return $this->belongsToMany('App\Resources\Eloquent\Models\Department', 'department_users');
}
Department Model
public function users()
{
return $this->belongsToMany(User::class, 'department_users');
}
For some reason, when I am trying to access through the user model $user->departments, it doesn't work - but $department->users does.
Outputting the eloquent query is as follows:
select `departments`.*, `department_users`.`user_id` as `pivot_user_id`, `department_users`.`department_id` as `pivot_department_id` from `departments` inner join `department_users` on `departments`.`id` = `department_users`.`department_id` where `department_users`.`user_id` is null
I can't seem to figure out why it is looking to see if department_users.user_id is null, when it should be looking for the user's id.
Any ideas?
Why don't you set up your models like it is suggested in the documentation here:
So your models would look something like this:
User Model
public function departments()
{
return $this->belongsToMany('path\to\your\model\Department');
}
Department Model
public function users()
{
return $this->belongsToMany(path\to\your\model\User);
}
Eloquent will join the two related model names in alphabetical order.So you don't need extra arguments when defining your relationship and Laravel also by default, makes model keys present on the pivot object. And then you can do something like this:
$department = path\to\your\model\Department::find(1);
foreach ($department->users as $user) {
echo $user;
}
For some reason, if I make the relationship the following - it works.
return $this->belongsToMany(Department::class, 'department_users')->orWhere('department_users.user_id', $this->id);
If anyone knows why, please let me know