LEFT OUTER JOIN in Rails 4
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")
Left join with rails 4
You will have to write the left join yourself.
Section.joins("left join questions on questions.section_id = sections.id")
.joins("left join answers on answers.question_id = questions.id")
Rails 4 Left outer join multiple tables with Group By and count
You could drop to SQL strings:
joins("LEFT OUTER JOIN comments ON comments.cuuser_id = cuuser.id LEFT OUTER JOIN likes ON likes.cuuser_id = cuuser.id LEFT OUTER JOIN messages on messages.cuuser_id = cuuser.id")
This isn't great. You're sacrificing some portability and the ability of ActiveRecord to guess the association.
If you used the Squeel gem you could use the following format:
joins{ [comments.outer, likes.outer, messages.outer] }
Squeel exposes Arel in a slightly more sane format, so you can do things like left outer joins while still guessing associations from the model definitions.
You could use Arel of course, but things get very clunky very quickly.
To get your counts, try:
select('cuusers.id, count(messages.id) as message_count, count(likes.id) as likes_count, count(comments.id) as comments_count').
They should be available as attributes on the returned objects, just like ordinary database fields.
How can I do a LEFT OUTER JOIN using Rails ActiveRecord?
I believe an includes
will use a LEFT OUTER JOIN
query if you do a condition on the table that the includes
association uses:
Group.includes(:user_group_cmb).where(user_group_cmbs: { user_id: 1 })
How to left outer joins with conditions
Because you have a general where
condition, you can use includes
. This will generate a LEFT OUTER JOIN
query:
Action.includes(:actions_users).where(actions_users: { user_id: true })
Or if you are using Rails 5+
, Active Record provides a finder method left_outer_joins
:
Action.left_outer_joins(:actions_users).where(actions_users: { user_id: true })
Multiple Left join with rails 4
You can do the following:
Section.joins(questions: :answer).where(answers: { user_id: USER_ID })
Some stuff to know:
- In the
joins
/includes
method, always use the exact same name as the relation - In the
where
clauses, always use the pluralized name of the relation (actually, the table's name, which is by default the model name in plural but can also be manually set)
Examples:
# Consider these relations:
User has_many :posts
Post belongs_to :user
# Usage of joins/includes & where:
User.includes(:posts).where(posts: { name: 'BlogPost #1' })
#^ ^
Post.joins(:user).where(users: { name: 'Little Boby Table' })
#^^ ^
Similar questions:
- How to query a model based on attribute of another model which belongs to the first model?
- association named not found perhaps misspelled issue in rails association
- Rails 3, has_one / has_many with lambda condition
- Rails 4 scope to find parents with no children
- Join multiple tables with active records
Related Topics
Does Db2 Have an "Insert or Update" Statement
Insert Values Where Not Exists
Convert Unixtime to Datetime SQL (Oracle)
Bulk/Batch Update/Upsert in Postgresql
Count Based on Condition in SQL Server
Finding Similar Strings with Postgresql Quickly
Not Null Constraint Over a Set of Columns
How to Kill a Running Select Statement
How Does a Recursive Cte Run, Line by Line
Check If the String Contains Accented Characters in SQL
SQL Server Converting Varbinary to String
How to Replace (Null) Values with 0 Output in Pivot