Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LEFT OUTER JOIN in Rails 4

I have 3 models:

class Student < ActiveRecord::Base   has_many :student_enrollments, dependent: :destroy   has_many :courses, through: :student_enrollments end  class Course < ActiveRecord::Base        has_many :student_enrollments, dependent: :destroy     has_many :students, through: :student_enrollments end  class StudentEnrollment < ActiveRecord::Base     belongs_to :student     belongs_to :course end 

I wish to query for a list of courses in the Courses table, that do not exist in the StudentEnrollments table that are associated with a certain student.

I found that perhaps Left Join is the way to go, but it seems that joins() in rails only accept a table as argument. The SQL query that I think would do what I want is:

SELECT * FROM Courses c LEFT JOIN StudentEnrollment se ON c.id = se.course_id WHERE se.id IS NULL AND se.student_id = <SOME_STUDENT_ID_VALUE> and c.active = true 

How do I execute this query the Rails 4 way?

Any input is appreciated.

like image 430
Khanetor Avatar asked Jun 23 '14 05:06

Khanetor


People also ask

How write query left outer join?

LEFT JOIN SyntaxON table1.column_name = table2.column_name; Note: In some databases LEFT JOIN is called LEFT OUTER JOIN.

What is left join and inner join?

Different Types of SQL JOINs Here are the different types of the JOINs in SQL: (INNER) JOIN : Returns records that have matching values in both tables. LEFT (OUTER) JOIN : Returns all records from the left table, and the matched records from the right table.

What are active records in Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.


2 Answers

You can pass a string that is the join-sql too. eg joins("LEFT JOIN StudentEnrollment se ON c.id = se.course_id")

Though I'd use rails-standard table naming for clarity:

joins("LEFT JOIN student_enrollments ON courses.id = student_enrollments.course_id") 
like image 123
Taryn East Avatar answered Oct 07 '22 19:10

Taryn East


If anyone came here looking for a generic way to do a left outer join in Rails 5, you can use the #left_outer_joins function.

Multi-join example:

Ruby:

Source.  select('sources.id', 'count(metrics.id)').  left_outer_joins(:metrics).  joins(:port).  where('ports.auto_delete = ?', true).  group('sources.id').  having('count(metrics.id) = 0').  all 

SQL:

SELECT sources.id, count(metrics.id)   FROM "sources"   INNER JOIN "ports" ON "ports"."id" = "sources"."port_id"   LEFT OUTER JOIN "metrics" ON "metrics"."source_id" = "sources"."id"   WHERE (ports.auto_delete = 't')   GROUP BY sources.id   HAVING (count(metrics.id) = 0)   ORDER BY "sources"."id" ASC 
like image 20
Blaskovicz Avatar answered Oct 07 '22 17:10

Blaskovicz