I have a table name EmployeeCourses that has a relationship with course_detail table and I have this eloquent query in Laravel:
$result = EmployeeCourses::where([['user_id', '=', '01'],['status','!=', 'Completed'] ])->whereDate('start_date','<=',$current_date)->with('course_details')->get();
Can I check if the course_details is not equal to null and if null or empty than don't include it in the $result?
I think you are looking for whereHas('relation').
$result = EmployeeCourses::where([
['user_id', '=', '01'],
['status','!=', 'Completed']
])->whereDate('start_date','<=',$current_date)
->whereHas('course_details')
->with('course_details')->get();
this method will return 'EmployeeCources' only if it has at least one 'Course Detail' is assigned.
Related
I have a function to get a pass a language number to get language categories record for API purpose. I use a database query statement to select categories table and join the category language table to get category id, parent_id and name (specified language). When execute return error and select the underlying SQL converted the language value to string (e.g. languages_id = 1). I google a lot and no ideas what's wrong. Can anyone advise how to resolve. Thanks a lot.
I tried to copy the underlying SQL to MySQL Workbench and remove the languages_id = 1 --> languages_id = 1 can working properly. I guess the 1 caused error.
Code Sample:
private function getCategories($language) {
$categories = DB::table('categories')
->select(DB::raw('categories.id, categories.parent_id, categories_translation.name'))
->join('categories_translation', function($join) use ($language) {
$join->on('categories_translation.categories_id', '=', 'categories.id');
$join->on('categories_translation.languages_id', '=', $language);
})
->where([
['parent_id' ,'=', '0'],
['categories.id', '=', $id]
])
->get();
return $categories;
}
Error return the converted SQL:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column '1' in 'on
clause' (SQL: select categories.id, categories.parent_id,
categories_translation.name from categories inner join
categories_translation on categories_translation.categories_id =
categories.id and categories_translation.languages_id = 1
where (parent_id = 0 and categories.id = 1))"
You are trying to join using a comparison to an scalar value, instead of a column. I think you actually want to put that comparison as a "where" condition, rather than a "join on"
->where([
['parent_id' ,'=', '0'],
['categories.id', '=', $id],
['categories_translation.languages_id', '=', $language]
])
there is another thing i just discover with your code. when joining table, you are suppose to be joining 'categories_translation.languages_id' with another table id field. in your case, it is not so. you are not joining 'categories_translation.languages_id' with any table field. so ideally, what you are going to do is this
private function getCategories($language) {
$categories = DB::table('categories')
->select(DB::raw('categories.id, categories.parent_id, categories_translation.name'))
->join('categories_translation', function($join) use ($language) {
$join->on('categories_translation.categories_id', '=', 'categories.id');
})
->where([
['parent_id' ,'=', '0'],
['categories.id', '=', $id]
['categories_translation.languages_id', '=', $language]
])
->get();
return $categories;
}
hope this helps
My script laravel eloquent like this :
$query = $this->item->select('a.*','b.attribute_code')
->from('items as a')
->join('attr_maps as b','b.number','=','a.number')
->groupBy('a.number');
foreach($param as $key => $value) {
$query = $query->having($key, '=', $value);
}
$query = $query->paginate(10);
My $param is dynamic. It can change
If $param is array('number'=>'1234'), it works. No error
If $param is array('description'=>'test'), there exist error : Unknown column 'description' in 'having clause'
I tried all fields in the table items. Only the number field works. Apparently because the number field is group by
How can I make all field in the items table works if using having?
The HAVING clause is used in the SELECT statement to specify filter conditions for a group of rows or aggregates. The HAVING clause executed after SELECT, so if you apply HAVING on columns which is not in group by or not in aggregate function then it will work as where, which is no use because select clause is already executed. And i think just because of that eloquent may throw exception, not sure though.
What you can do, check your param key if it is in group by fields then apply having if not then add it as where condition like this.
$query = $this->item->select('a.*','b.attribute_code')
->from('items as a')
->join('attr_maps as b','b.number','=','a.number')
->groupBy('a.number');
foreach($param as $key => $value) {
if($key== 'number'){
$query = $query->having($key, '=', $value);
}else{
$query = $query->where($key, '=', $value);
}
}
you can check here WHERE vs HAVING
It's because Laravel's Eloquent ORM is active-record inspired and very database centric.
In the end, it's mainly because having is an sql concept which is used to filter rows in aggregate results.
In short, you're dealing with patches to problems in the SQL language which the Eloquent ORM has not abstracted away.
I'm having trouble with a one-to-many relationship in Laravel 5.5.
I have two tables, one for blog posts and one for authors. The posts table has an author_id column and it's populated with valid author IDs for each blog post. author_id is defined as a foreign key in the posts table migration.
When I load a view that uses the query the author is null because the author_id isn't being included in the generated query.
Post model:
public function author(): BelongsTo
{
return $this->belongsTo(Author::class);
}
I also tried explicitly listing the keys with the same result:
return $this->belongsTo(Author::class, 'author_id', 'id');
Post repository:
public function getPostBySlug(string $slug)
{
return $this->model
->select(
'posts.title',
'posts.contents',
'posts.published_at'
)
->with(['author:first_name,last_name,slug'])
->where('posts.slug', '=', $slug)
->whereNotNull('posts.published_at')
->first();
}
Generated query:
select `first_name`, `last_name`, `slug`
from `authors` where `authors`.`id` in ('')
and `authors`.`deleted_at` is null
You didn't select the posts.author_id so without the author_id the relationship couldn't be made, either select * or exclude the select statement or include posts.author_id in your select statement, for example:
$this->model
->select(
'posts.author_id',
'posts.title',
'posts.contents',
'posts.published_at'
)
// rest of the code ...
The foreign key (posts.author_id) has to be available to build the relationship with authors.
Try this
$users = DB::table('posts')
->leftJoin('authors', 'authors.id', '=', 'posts.user_id')
->select('posts.author_id','posts.title','posts.contents','posts.published_at',
'authors.first_name','authors.last_name','authors.slug')
->where('posts.slug', '=', $slug)
->whereNotNull('posts.published_at')
->first();
tray the ralation in the following way
:
return $this->belongsTo('namespace\author');
or reverse way
return $this->hasMany('namespace\author');
Here is my problem. Please help
I have these two tables Course and Students. Students take courses. Now I want to get a specific course as shown then see in student table if this course is taken by the student.
Course table:
id
name
description
Student table:
user_id
course_id
semester
address
phone
What I tried:
$course = Course::where('name', '=', $data["id"]);
$enroll= Students::where('course_id', '=', $course["id"]);
$enroll= Students::where('course_id', '=', $course->id);
$$result=$course->toArray();
$enroll= Students::where('course_id', '=', $course["id"]);
I need to search the variable where the return value of eloquent query is stored.
For a specific user and a specific course you can get the collection of records from student table with the following query:
$courceId = 1;
$userId = 1;
$enrolled = Students::where('course_id', $courseId)
->where('user_id', $userId)
->count() > 0;
$enrolled will have true or false value
You can use eloquent relationship to obtain this in a much better way. However you can do this like the following assume your course name is $course_name:
$course = Course::where('name', '=', $course_name)->first();
if($course!=null){
$enroll= Students::where('course_id', '=', $course->id)->get();
}
and then you can check if it has data or not like
if($enroll!=[]){
echo 'this course has been taken by some student';
}
Here some student are the $enroll student.
I got category_to_news and news_main table
category_to_news
news_id int
name varchar
title timestamp
news_main
id int
title varchar
image varchar
created_at timestamp
how to return by news_main's field and category_news's field ? I've tried this method and it's not work
$posts = Categorytonews::with(array(
'Newsmain' => function($query)
{
$query->orderBy('id', 'DESC')->select(array('title', 'id', 'created_at', 'image'));
}
))
->get( );
You need join for this because with() runs another query, so ordering there won't do the job:
$posts = Categorytonews::with('Newsmain') // get all fields from Newsmain
->join('news_main', 'category_to_news.news_id', '=', 'news_main.id') // join for ordering
->orderBy('news_main.id','desc') // order by joined field
->get('category_to_news.*'); // select only main table, you don't need joined fields
// on Categorytonews model - they will be loaded by with()
$posts = Categorytonews::with(array('Newsmain' => function($query)
{
$query->select(array('title', 'id', 'created_at', 'image'))->orderBy('id', 'DESC');
}))->get();