Last active
July 4, 2019 05:11
-
-
Save jmscholen/3e9011408227e6dd1f0b55b9be714e42 to your computer and use it in GitHub Desktop.
Rails Arel Complex Multi Join Query
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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