I want to make a relation between my tables with belongToMany.
These are my three tables, that I want to connect.
fairkatert_task
-id
-user_id
-name
fairkatert_milestone
-id
-name
fairkatert_task_assign_milestone
-id
-milestone_id
-task_id
I use the belongToMany Method from Eloquent.
public function getTasks()
{
return $this->belongsToMany(
'App\Http\Models\Task',
'fairkatert_task_assign_milestone',
'milestone_id',
'task_id'
);
}
And i only get the following SQL Error Message:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'milestone_id' in 'where clause' (SQL: select * from `fairkatert_task` where `fairkatert_task`.`deleted_at` is null and (`milestone_id` is null))
But I think I've done everything right but,but can't my mistake.
Expanding on Josef's comment, you are looking directly at the answer - which you have acknowledged.
However you're struggling to understand:
I did, but i do not unterstand why it's looking for milestone_id in the "fairkatert_task" table.
Reading Laravels documentation on a belongsToMany relationship it states:
In addition to customizing the name of the joining table, you may also customize the column names of the keys on the table by passing additional arguments to the belongsToMany method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to:
return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
Your relationship is:
public function getTasks()
{
return $this->belongsToMany(
'App\Http\Models\Task',
'fairkatert_task_assign_milestone',
'milestone_id',
'task_id'
);
}
The third argument is the foreign key name of the model on which you are defining the relationship
This means your third argument, milestone_id is trying to be found by fairkatert_task.
Oh my god i found my problem ...
I had in my controller still an old method, that i load
Related
This issue happens for me on Backpack v5 and Laravel 8 (although I do reproduce it on Laravel 9 as well).
My issue happens when I have a setup similar to this one : https://backpackforlaravel.com/docs/5.x/crud-fields#manage-related-entries-in-the-same-form-create-update-delete
Just to clarify here:
Two models related by a 1-n relationship
Those models override their $primaryKey attribute (as their primary key is not "id")
the "parent" models CRUD that has a 'type' => 'relationship' with 'subfields' to add children through a "repeatable" type field
This is the error I get (with the Monsters and Stories example):
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id_story' in 'where clause'
select * from `monsters` where `monsters`.`story_id` = 5 and `monsters`.`story_id` is not null and (`id_story` is null) limit 1
The stack trace leads me to vendor\backpack\crud\src\app\Library\CrudPanel\Traits\Create.php:310
Here is how I reproduced it on the Backpack demo projet:
Install demo project following instructions here :https://backpackforlaravel.com/docs/4.1/demo#demo-installation
Rename monsters primary key in table to id_monster and stories primary key to id_story
Add the $primaryKey overrides on corresponding models like so:
protected $primaryKey = 'id_monster'; // In Monster.php
protected $primaryKey = 'id_story'; // In Story.php
Add correct "foreignKey" parameters to relation method like so:
// In Story.php
public function monsters()
{
return $this->hasMany(\App\Models\Monster::class, 'story_id');
}
// In Monster.php
public function story()
{
return $this->belongsTo(\App\Models\Story::class, 'story_id');
}
Now add a story with a monster through the Crud panel and you should reproduce the error.
I'm thinking I'm probably missing something but I just can't figure it out. I'm pretty sure the relations are properly defined and I'm wondering if it's not a bug in Backpack.
Thanks for your help !
UPDATE
This is indeed an issue that has been reported here
I'm seeing that you are using "story_id" in both relations (Story.php and Monster.php).
In Story.php you should use :
public function monsters()
{
return $this->hasMany(\App\Models\Monster::class, 'story_id');
}
And In Monster.php you should use :
public function story()
{
return $this->belongsTo(\App\Models\Story::class, 'monster_id');
}
Also be careful that when you are trying to set relationships in migrations and in models, you are setting correct foreign keys both in migration and models.
I'm creating an application wherein users can be assigned to multiple organisations, and organisations can have many users - many-to-many relationships.
I want to be able to do something like this:
$user->organisations()->get() as well as $organisation->users()->get()
I have a users table...
I have an organisations table...
Uh! users-organisations, organisations-users!
and I have a user_orgs pivot/mapping/etc. table
Note
The user_orgs table has an org_id field, and a user_id field.
Eloquent assumes and expects organisation_user - but that is not what I have named my table, nor do I want to rename.
I set up the following
App/Organisation.php
public function users(){
return $this->belongsToMany("App\User");
}
and on user:
App/User.php
public function organisations(){
return $this->belongsToMany("App\Organisation");
}
And then I test this:
Route::get('/test-route', function(){
$u = App\User::first();
return $u->organisations()->get();
});
and get the following error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db.organisation_user' doesn't exist (SQL: select organisations.*, organisation_user.user_id as pivot_user_id, organisation_user.organisation_id as pivot_organisation_id from organisations inner join organisation_user on organisations.id = organisation_user.organisation_id where organisation_user.user_id = 1)
The two questions in my mind are, one; how do I specify to Eloquent, to use user_orgs instead of assuming organisation_user, the same way I can override the tableName or primaryKey on a model? Two: how can I specify the foreignKey column, such that it uses user_orgs.org_id and not user_orgs.organisation_id?
But please do suggest alternatives.
Thanks all, in advance.
You can set the name of the pivot table by passing it as the second argument to the belongsToMany() relationship, like below:
public function users(){
return $this->belongsToMany("App\User", "user_orgs");
}
public function organisations(){
return $this->belongsToMany("App\Organisation", "user_orgs");
}
Documentation:
https://laravel.com/docs/5.8/eloquent-relationships#many-to-many
As mentioned previously, to determine the table name of the relationship's joining table, Eloquent will join the two related model names in alphabetical order. However, you are free to override this convention. You may do so by passing a second argument to the belongsToMany method.
I have my class "Product_reviews", which is binded to the class "Products" like this:
Products.php:
public function product_reviews()
{
return $this->hasMany('App\Product_reviews');
}
Product_reviews.php:
public function products()
{
return $this->belongsTo('App\Products');
}
Foreign key for table "Product_reviews" is 'product_id'.
So, in the controller I'm trying to get all data:
$products = Products::with('product_reviews')->get();
And... I have an error saying that product_id can't be found:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'product_reviews.products_id' in 'where clause' (SQL: select * from `product_reviews` where `product_reviews`.`products_id` in (1, 2))
Correct me if I'm wrong, but I think the query builder is adding '_id' to the class' name. It can be fixed by going to the table "product_reviews" and changing 'product_id' by 'products_id'... Or maybe I could pass all classes' and tables' names to singular.
So my question is: What other options do I have in order to make the query builder know the proper column's name?
Your models should be named in the singular form, and then Laravel will not attempt to use the plural form of the column name in the generated SQL query.
In your case, the Products model should be called Product. Remember that a model represents one record in your database, so the singular form is correct.
You overwrote this behaviour by manually setting the foreign field in your $this->hasMany(..) relationship, which skirted around the issue, but didn't fix the underlying cause.
Additionally, you should avoid using snake_cased class names, as it violates PSR. Your Product_reviews model should be called ProductReview.
Ok, I got it:
In Products.php:
return $this->hasMany('App\Product_reviews');
I added 2 more parameters to the function hasMany, like this:
return $this->hasMany('App\Product_reviews','product_id','id');
These parameters specify the id's names.
This post really helped:
laravel-hasmany-and-belongsto-parameters
Anyhow I think it may be good in long terms to do what Davit and hktang say and rename my classes with singular names. Thanks for your answers.
I'm trying to get information associated with an application in my database.
Each application has 1 applicant.
Each application has 1 puppy.
I'm returning a view with an eloquent query like this:
$active_applications = Application::with('applicant', 'puppy')->where('kennel_id', '=', $user_kennel->id)->get();
And I have some relationships defined in my application model like so:
public function puppy(){
return $this->belongsTo('App\Puppy');
}
public function applicant(){
return $this->belongsTo('App\User');
}
When the view loads, I'm able to get the information associated with 'puppy'. It retrieves properly. The applicant, however stays null.
I have, in my applications table, a column named "user_id", which I was hoping it would use value in that column to search the users table 'id', and retrieve information on the user. It stays null, however. The following is a dd() of the variable in question:
Am I missing something obvious? Why would it retrieve one and not the other?
EDIT: the puppy table
Your relation is wrong -
public function applicant(){
return $this->belongsTo('App\User');
}
When you don't pass the foreign key as a parameter, laravel looks for the method name + '_id'. Therefore in your case laravel is looking for the column applicant_id in your application table.
So, to get results there are two ways -
1) You need to either change your method name -
public function user(){
return $this->belongsTo('App\User');
}
**2) Pass foreign key as the second parameter - **
public function applicant(){
return $this->belongsTo('App\User', 'user_id');
}
Laravel 5.6 doc - belongsTo
If its a One to Many(Inverse) Relation -
Eloquent determines the default foreign key name by examining the name
of the relationship method and suffixing the method name with a _
followed by the name of the primary key column.
If its a One to One Relation -
Eloquent determines the default foreign key name by examining the name
of the relationship method and suffixing the method name with _id.
Review Laravel doc for more details
Try the following line instead:
$active_applications = Application::with(['applicant', 'puppy'])->where('kennel_id', '=', $user_kennel->id)->get();
As far as I know, multiple "with" should be passed as array.
Adjust the relationship as well
public function applicant(){
return $this->belongsTo('App\User', 'user_id');
}
I've created a one-to-many relationship between a Jobs Model and Permits model. I've recently discovered the awesome tool of Tinker so I've been using it to test my models. When I run Job::with('steps')->find(1); I get this error
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'steps.job_id' in 'where clause' (SQL: select * from `steps` where `steps`.`job_id` in (1))'
Here's my Job Model
public function steps ()
{
return $this->hasMany('MyfirstApp\Step');
}
Here's my Step Model
public function Job ()
{
return $this->belongsTo('MyFirstApp\Job');
}
I've already set up the foregin key in the Jobs Table so I'm not sure what the error can be. Any ideas?
Table Structure for reference
For your relationship, Job has many Steps, you have assigned wrong foreign key.
In your case steps table should contain job_id rather than job contains steps_id.
Solution:
Remove steps_id from job table.
Set job_id in steps table as a foreign key.
Try it
You are set wrong relationship on model
Job Model
public function steps ()
{
return $this->belongsTo('MyfirstApp\Step');
}
Step Model
public function Job ()
{
return $this->hasMany('MyFirstApp\Job');
}