forked from fixin.me/fixin.me
		
	defaults_diff returns base Units where needed
This commit is contained in:
		
							parent
							
								
									1790f2e7f2
								
							
						
					
					
						commit
						6c678b6560
					
				@ -14,16 +14,18 @@ class Unit < ApplicationRecord
 | 
				
			|||||||
  validates :multiplier, numericality: {other_than: 0}, if: :base
 | 
					  validates :multiplier, numericality: {other_than: 0}, if: :base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  scope :defaults, ->{ where(user: nil) }
 | 
					  scope :defaults, ->{ where(user: nil) }
 | 
				
			||||||
  scope :with_defaults, ->{ self.or(Unit.where(user: nil)) }
 | 
					 | 
				
			||||||
  scope :defaults_diff, ->{
 | 
					  scope :defaults_diff, ->{
 | 
				
			||||||
 | 
					    actionable_units = Arel::Table.new('actionable_units')
 | 
				
			||||||
 | 
					    units = actionable_units.alias('units')
 | 
				
			||||||
    bases_units = arel_table.alias('bases_units')
 | 
					    bases_units = arel_table.alias('bases_units')
 | 
				
			||||||
    other_units = arel_table.alias('other_units')
 | 
					    other_units = arel_table.alias('other_units')
 | 
				
			||||||
    other_bases_units = arel_table.alias('other_bases_units')
 | 
					    other_bases_units = arel_table.alias('other_bases_units')
 | 
				
			||||||
    sub_units = arel_table.alias('sub_units')
 | 
					    sub_units = arel_table.alias('sub_units')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Unit.with(units: self.with_defaults).left_joins(:base)
 | 
					    Unit.with_recursive(actionable_units: [
 | 
				
			||||||
      # Exclude Units that are/have default counterpart
 | 
					      Unit.with(units: self.or(Unit.defaults)).left_joins(:base)
 | 
				
			||||||
        .where.not(
 | 
					        .where.not(
 | 
				
			||||||
 | 
					          # Exclude Units that are/have default counterpart
 | 
				
			||||||
          Arel::SelectManager.new.project(1).from(other_units)
 | 
					          Arel::SelectManager.new.project(1).from(other_units)
 | 
				
			||||||
            .outer_join(other_bases_units)
 | 
					            .outer_join(other_bases_units)
 | 
				
			||||||
            .on(other_units[:base_id].eq(other_bases_units[:id]))
 | 
					            .on(other_units[:base_id].eq(other_bases_units[:id]))
 | 
				
			||||||
@ -32,11 +34,12 @@ class Unit < ApplicationRecord
 | 
				
			|||||||
                .and(other_units[:symbol].eq(arel_table[:symbol]))
 | 
					                .and(other_units[:symbol].eq(arel_table[:symbol]))
 | 
				
			||||||
                .and(other_units[:user_id].is_distinct_from(arel_table[:user_id]))
 | 
					                .and(other_units[:user_id].is_distinct_from(arel_table[:user_id]))
 | 
				
			||||||
            ).exists
 | 
					            ).exists
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .select(
 | 
				
			||||||
 | 
					          arel_table[Arel.star],
 | 
				
			||||||
          # Decide if Unit can be im-/exported based on existing hierarchy:
 | 
					          # Decide if Unit can be im-/exported based on existing hierarchy:
 | 
				
			||||||
          # * same base unit symbol has to exist
 | 
					          # * same base unit symbol has to exist
 | 
				
			||||||
          # * unit with subunits can only be ported to root
 | 
					          # * unit with subunits can only be ported to root
 | 
				
			||||||
      ).select(
 | 
					 | 
				
			||||||
        arel_table[Arel.star],
 | 
					 | 
				
			||||||
          arel_table[:base_id].eq(nil).or(
 | 
					          arel_table[:base_id].eq(nil).or(
 | 
				
			||||||
            (
 | 
					            (
 | 
				
			||||||
              Arel::SelectManager.new.project(1).from(other_units)
 | 
					              Arel::SelectManager.new.project(1).from(other_units)
 | 
				
			||||||
@ -44,18 +47,24 @@ class Unit < ApplicationRecord
 | 
				
			|||||||
                .where(
 | 
					                .where(
 | 
				
			||||||
                  other_units[:symbol].eq(arel_table[:symbol])
 | 
					                  other_units[:symbol].eq(arel_table[:symbol])
 | 
				
			||||||
                    .and(other_units[:user_id].is_distinct_from(arel_table[:user_id]))
 | 
					                    .and(other_units[:user_id].is_distinct_from(arel_table[:user_id]))
 | 
				
			||||||
              )
 | 
					                ).exists.not
 | 
				
			||||||
              .exists.not
 | 
					 | 
				
			||||||
            ).and(
 | 
					            ).and(
 | 
				
			||||||
              Arel::SelectManager.new.project(1).from(other_bases_units)
 | 
					              Arel::SelectManager.new.project(1).from(other_bases_units)
 | 
				
			||||||
                .where(
 | 
					                .where(
 | 
				
			||||||
                  other_bases_units[:symbol].is_not_distinct_from(bases_units[:symbol])
 | 
					                  other_bases_units[:symbol].is_not_distinct_from(bases_units[:symbol])
 | 
				
			||||||
                    .and(other_bases_units[:user_id].is_distinct_from(bases_units[:user_id]))
 | 
					                    .and(other_bases_units[:user_id].is_distinct_from(bases_units[:user_id]))
 | 
				
			||||||
              )
 | 
					                ).exists
 | 
				
			||||||
              .exists
 | 
					 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
          ).as('portable')
 | 
					          ).as('portable')
 | 
				
			||||||
      )
 | 
					        ),
 | 
				
			||||||
 | 
					      # TODO: replace AS and MIN with Arel
 | 
				
			||||||
 | 
					      # TODO: turn off ONLY_FULL_GROUP_BY
 | 
				
			||||||
 | 
					      # Add missing base Units. Duplicates will be removed by final group(), as
 | 
				
			||||||
 | 
					      # actionable Units will differ on 'portable' column and can't be UNION-ed.
 | 
				
			||||||
 | 
					      arel_table.join(actionable_units).on(actionable_units[:base_id].eq(arel_table[:id]))
 | 
				
			||||||
 | 
					        .project(arel_table[Arel.star], 'NULL AS portable')
 | 
				
			||||||
 | 
					    ]).select(units: column_names)#, 'MIN(units.portable)' => :portable)
 | 
				
			||||||
 | 
					      .from(units).group(Unit.column_names)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  scope :ordered, ->{
 | 
					  scope :ordered, ->{
 | 
				
			||||||
    left_outer_joins(:base)
 | 
					    left_outer_joins(:base)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user