I have subject table that contains
id name
and languages table that contains
id subject_id
and division table
id name
finally subject-division table (pivot table)
id subject_id division_id
now exist one-To-one relationship between subject table and languages table and many-To-many relationship between subject table and division table, i need to pluck only the subjects of subject table without the languages by using the relationship function
now i can get the languages only of the subject table of the relationship function In Division Model as the following
public function langSubject ()
{
return $this->belongsToMany('Subject' , 'subject_division','division_id','subject_id')
->join('lang_subject', 'lang_subject.subject_id' ,'=', 'subject.id')->get();
}
But till now I can't get the subjects only without the languages
Any Suggestions ?
You need to add the clause ->select('tableName1.fieldName1','tableName2.fieldName2','tableName3.fieldName3') to your statement after the join statement to get the tableName.fieldName and you may need to use leftJoin instead of join to get the results whether if there is a match or not.
Check out Eloquent relationship documentation -> sub headline "Querying Relationship Existence". There it mentions ::has method, which you could use in fashion
Division::has('subject.lang', '<', 1)->get()
Or at least that's the theory. Haven't had the need for it yet ;-)
It should be supported by Laravel 4 as well.
Related
I have a problem in my project
I'm trying to do a query with the table "Asignaciones", this table save the records for students and teachers asignations. (The teachers can comment the works of students and can see only the students that are asigned) The principal problem is that all the users is on the same table and when i try to return a names just have one.
$asignaciones = DB::table('asignaciones')
->join('users as students','students.id',
'=','asignaciones.id_student')
->join('users as teachers','teachers.id',
'=','asignaciones.id_teacher')
->select('asignaciones.id','students.name',
'teachers.name')->get();
return $asignaciones;
I need to get two names (Maybe changing the column name like a users table) to show in a table
Thanks for your time and answers! :)
Define unique aliases in your select clause for student name and teacher name
->select('asignaciones.id','students.name as student_name','teachers.name as teacher_name');
Right now single alias name is returned for teacher and student name in the returned result set, object cannot have 2 keys with same name so one of the names got override while laravel maps the DB result to object or collection of objects
Suppose I have a Laravel 5.5 app with four models:
Class, Student, Assignment and AssignmentSubmission
A Class belongs to many Students, a Student belongs to many Classes and an AssignmentSubmission belongs to an Assignment, a User, and a Class.
So the tables look like this:
classes:
id
name
students:
id
name
class_student:
class_id
student_id
assignments:
id
name
assignment_submissions:
id
class_id
student_id
assignment_id
Now, in a query builder class I need to construct a query that returns the Students that belong to a Class with an extra column called total_assignment_submissions with a tally of how many assignments that student has submitted for that class only.
My first port of call was the following:
$class->students()->withCount('assignmentSubmissions')->get();
But that returns the total assignment submissions for that student for all classes.
The following mySql query returns the right data:
SELECT *,
(SELECT Count(*)
FROM `assignment_submission`
WHERE `student_id` = `students`.`id`
AND `class_id` = ?) AS total_assignment_submissions
FROM `students`
INNER JOIN `class_student`
ON `students`.`id` = `class_student`.`student_id`
WHERE `class_student`.`class_id` = ?
But I can't seem to get the selectSub() addSelect() and raw() calls in the right order to get what I want. It seems that I only do it with raw queries but the event id will be unsanitized or otherwise I can do it but it only returns the assignment_count field and not the rest of the fields for the student.
$class->students()
->selectSub(
AssignmentSubmission::selectRaw('count(*)')
->whereClassId($class->id)->getQuery(),
'total_assignment_submissions'
)->toSql();
There must be a way to do this. What am I missing here?
withCount() can be constrained.
$class->students()->withCount(['assignmentSubmissions' => function($q) use($course_id){
$q->where('course_id', $course_id);
}])->get();
This will limit the count to that particular course.
I have one table employee_profile, I am using this table for searching employees, it's columns are id, user_id, experience, salary.
I have two more tables
employee_keyskills with columns user_id and keyskills_id
employee_preferred_cities with columns user_id and city_id
Now I have to find employees with experience, salary, keyskills[], salaries[]
Just I need help in finding results from hasMany associated tables, means employees should be filtered only with specified keyskills[] and cities[] from employee_keyskills and employee_preferred_citites tables.
you should use whereHas which allow you to add customized constraints to a relationship constraint.
check this
https://laravel.com/docs/5.4/eloquent-relationships#querying-relationship-existence
I have 2 tables one of them stores students and the other one managers
students have name surname,
eventually managers have name and surname too.
I also store added_by in students table to check which manager added the student.
With the query I join tables
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->get();
lets say student is
Name Surname Added_by
Jon Doe 1
and Manager is
id name surname
1 jane doe
So when I join those 2 tables with the query I give above. My student becomes
Jane doe because of name conflicts in those 2 tables.
Simply manager's name overwrites to student's name since both columns named same.
I could actually join only some columns in managers table however I need this name column to print out added_by column with the managers name
and of course I can change columns name to something else in a table however this would be too much work because I have to refactor each query in my application one by one and also test everything from scratch
so my question is how can I join those 2 tables and prevent conflictions on columns with same name?
Try using this:
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->select('students.*','managers.name as m_name','managers.surname as m_s_name','managers.other_column_if_needed','managers.another_column_if_needed')
->get();
This way your managers table's name column will be treated as m_name and surname column will be treated as m_s_name
I ran into a similar issue earlier today, the 'get' method takes in an array of the column names which you want in the result as parameter. Therefore to prevent the conflicts you have to give those columns an alias name like so :
$students = \App\Student::with('payment')->with('discontinuities')
->Join('managers','students.added_by','=','managers.id')
->get(['students.*', 'managers.name as managers_name', 'managers.surname as managers_surname', 'managers.other_column_if_needed']);
My guess would be that you should specify column names and tables in the get() part of your query.
example:
$students = \App\Student::with('payment')->with('discontinuities')
->leftJoin('managers','students.added_by','=','managers.id')
->get(['managers.Name', 'managers.Surname', 'students.name', 'students.surname']);
I want to retrieve all the tasks details (task_title etc) belonging to one author_id (author2 in this case).
Tests table
author_id task_id
author2 task_1
author2 task_2
Tasks table
task_id task_title
task_1 task_title_1
task_2 task_title_2
Author table
author_id author_name
author_2 authorTwo
Model test.php
public function tasks()
{
return $this->belongsTo('Task','task_id');
}
TestsController.php
public function index()
{
$test=Test::find('author2')->tasks()->get();
return View::make('tests.index', compact('tests'));
}
and the query SQL:
select * from `tests` where `author_id` = 'author2' limit 1
select * from `tasks` where `tasks`.`task_id` = 'task1'
But actually in tasks table, there are more than one value related to author 2 (in this case task 1 and task2 ) but as the sql only illustrates task1.
How can I remove the limit 1 restriction to retrieve all the tasks belonging to author 2?
There are multiple issues with that. The main ones being:
You're using the wrong relationship for a many-many, look into belongsToMany()
It looks like you're trying to look up on a composite key which is not supported
Find is intended to fetch only one record, and does not limit the result set of a relationship. As shown by your SQL, you're not limiting your tasks by one, you're limiting tests. Use get() in conjunction with where() when you need to fetch multiple records.
Here is a link to the documentation to get you started - http://four.laravel.com/docs/eloquent
Test::where("author_id","=","author2")->get()
You should not be using find for anything that is not a primary key, by the way. This is the aim of find: it fetches one item as it assumes that the key it searches for is primary auto-increment (i.e. unique)