Module: Bitfields::ClassMethods

Defined in:
lib/bitfields.rb

Instance Method Summary collapse

Instance Method Details

#bitfield(column, *args) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/bitfields.rb', line 64

def bitfield(column, *args)
  column = column.to_sym
  options = extract_bitfield_options(column, args)
  bitfield_args << [column, options.dup]

  store_bitfield_values column, options
  add_bitfield_methods column, options
end

#bitfield_arel(bit_values) ⇒ Object

Arel-based predicate for the given bits. Unlike the string SQL built by bitfield_sql, an Arel predicate carries its table relation, so it composes with eager loading (includes/references/merge) without the silent no-match that strings cause on ActiveRecord >= 6.1.



101
102
103
104
105
106
# File 'lib/bitfields.rb', line 101

def bitfield_arel(bit_values)
  predicates = group_bits_by_column(bit_values).sort_by { |column, _| column.to_s }.map do |column, values|
    bitfield_arel_by_column(column, values)
  end
  predicates.reduce(:and)
end

#bitfield_bits(values) ⇒ Object



73
74
75
76
# File 'lib/bitfields.rb', line 73

def bitfield_bits(values)
  bits = bitfields.values.reduce({}, :merge)
  values.sum { |bit, on| on ? bits.fetch(bit) : 0 }
end

#bitfield_column(bit_name) ⇒ Object



78
79
80
81
82
83
# File 'lib/bitfields.rb', line 78

def bitfield_column(bit_name)
  found = bitfields.find { |_, bits| bits.key?(bit_name.to_sym) }
  raise "Unknown bitfield #{bit_name}" unless found

  found.first
end

#bitfield_sql(bit_values, options = {}) ⇒ Object



85
86
87
88
# File 'lib/bitfields.rb', line 85

def bitfield_sql(bit_values, options = {})
  bits = group_bits_by_column(bit_values).sort_by { |column, _| column.to_s }
  bits.map { |column, values| bitfield_sql_by_column(column, values, options) }.join(' AND ')
end

#set_bitfield_sql(bit_values) ⇒ Object

rubocop:disable Naming/AccessorMethodName -- public API name, kept for backwards compatibility



91
92
93
94
# File 'lib/bitfields.rb', line 91

def set_bitfield_sql(bit_values)
  bits = group_bits_by_column(bit_values).sort_by { |column, _| column.to_s }
  bits.map { |column, values| set_bitfield_sql_by_column(column, values) }.join(', ')
end

#with_bitfields(bit_values) ⇒ Object

Convenient named query: User.with_bitfields(vendor: true, zany: false)



109
110
111
# File 'lib/bitfields.rb', line 109

def with_bitfields(bit_values)
  where(bitfield_arel(bit_values))
end

#without_bitfields(bit_values) ⇒ Object



113
114
115
# File 'lib/bitfields.rb', line 113

def without_bitfields(bit_values)
  where.not(bitfield_arel(bit_values))
end