Reputation: 6355
Hi I am building an application and I have a table for example projects and then settings. However they do not have a foreign key with each other and i have other tables such as tasks, clients etc. And these have settings which I am planning to save in the settings table.
The settings table has a column of type, which i will fill with the related model name e.g. project
. Anyway when i am fetching a project I also want to fetch a the settings where the type = project. So I've tried to do a table join instead however this has thrown the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'project' in 'on clause' (SQL: select * from `projects` inner join `settings` on `type` = `project`)
The code I've used is as follows:
return \Project::()->join('settings', 'type', '=', 'project')->get();
I see what the problem is, its looking for a column called project however there isn't one. I suppose what i want to do is use eloquent and a query function to join the table and then query the settings table where type = project. does anyone know how i can do this?
I've tried to put this in my model as so so
settings.php
public function sprint() {
return \Setting::where('type', '=', 'sprint')->get();
}
and sprint.php
public function settings() {
return \Setting::where('type', '=', 'sprint')->get();
}
however I get this error Call to undefined method
Illuminate\Database\Eloquent\Collection::addEagerConstraints() and I've called it using this method:
return Sprint::with(['settings'])->get();
what have i done wrong here?
Upvotes: 0
Views: 4420
Reputation: 5332
Because you are not referencing the table names and you are comparing columns. Instead, what you need is a where
statement within your join condition to compare with a value.
return DB::table('projects')
->join('settings', function ($join) {
$join->where('settings.type', '=', 'project');
})->get();
But you should better get settings and projects one by one as all identical settings columns will be added to your projects rows which is not good.
$data = [];
$data['projects'] = Project::all();
$data['settings'] = Settings::where('type', '=', 'project')->first();
return $data;
Update:
Within your Sprint model
public function scopeWithType()
{
return static::join('settings', function ($join) {
$join->where('settings.type', '=', 'sprint');
});
}
Then within the controller
Sprint::withType()->get();
Upvotes: 4
Reputation: 452
I have not tried but I think this is what you want. This is how we do subqueries or query joins with where clause.
return \Project::join('settings', function($q) {
$q->where('type', '=', 'project');
})->get();
your code looks for records matching project
field in the table settings
and type
field in the project
table, which is not the case.
Upvotes: 1