Skip to content

Instantly share code, notes, and snippets.

@jmscholen
Last active July 4, 2019 05:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmscholen/3e9011408227e6dd1f0b55b9be714e42 to your computer and use it in GitHub Desktop.
Save jmscholen/3e9011408227e6dd1f0b55b9be714e42 to your computer and use it in GitHub Desktop.
Rails Arel Complex Multi Join Query
def self.get_docs(some_input, required_docs, optional_docs, base_id = nil)
base_req = self.get_parameters_from_request(some_input)
user_department_id = some_input.user_department.try("id") || -1
doc = Document.arel_table
dept = Department.arel_table
dept_rule = DepartmentRule.arel_table
dept_code = DepartmentRuleCode.arel_table
debt_state = DepartmentRuleState.arel_table
scope :base_scope, -> {
joins(:rules,:codes, :states, :documents)
.includes(:line_of_business)
.where(doc[:parent_document_id].eq(nil)
.or(doc[:parent_document_id].eq(doc[:id])))
.where(doc[:deparment_id].eq(some_input.managing_department.id))
.where(dept_rule[:user_department_id].eq(nil)
.or(dept_rule[:user_department_id].eq(some_input.department &&
some_input.department.id)))
.where(doc[:user_id].eq(nil)
.or(doc[:user_department_id].eq(some_input.department &&
some_input.department.id)))
.where(lob[:code].in(doc[:line_of_businesses])
.or(dept_rule[:line_of_business_id].eq(nil)))
.where(dept_code[:classcode].in(doc[:class_code])
.or(dept_code[:classcode].eq(nil)))
.where(dept_state[:state].in(doc[:state])
.or(dept_state[:state].eq(nil)))
.where(dept_rule[:effective_date].lteq(some_input.effective_date)
.or(dept_rule[:effective_date].eq(nil)))
.where(dept_rule[:expiration_date].gteq(some_input.effective_date)
.or(dept_rule[:expiration_date].eq(nil))) }
if base_id
Base = Base.find(base_id)
if Base
if Base.is_a? DepartmentBase
scope :base_condition, -> {
where(dept_rule[:base_id].eq(base_id))
.where(dept_rule[:user_department_id].eq(nil)
.or(dept_rule[:user_department_id].eq(department_id))) }
else
scope :base_condition, -> {
where(dept_rule[:base_id].eq(base_id)
.or(dept_rule[:optional_for_all_departments].eq(1)))
.where(dept_rule[:user_department_id].eq(nil)
.or(debt_rule[:user_department_id].eq(department_id))) }
end
end
else
scope :base_condition, -> {
where(dept_rule[:base_id].eq(nil))
.where(debt_rule[:optional_for_all_departments].eq(0)) }
end
results = self.base_scope.base_condition.uniq.order(:sequence)
end
@jmscholen
Copy link
Author

jmscholen commented Aug 1, 2017

another option for multiple joins:
Document.joins(:departments => [:rules, :codes, :states])

where departments has association with document, but :rules, :codes, and :states are have association with department and not document.
Produces the following:
SELECT documents.* FROM documents INNER JOIN departments ON departments.document_id = documents.id INNER JOIN rules ON rules.department_id = departments.id INNER JOIN codes ON codes.department_id = departments.id INNER JOIN states ON states.department_id = department.id

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment