Rails bitwise, enum with super powers

TL;DR

Handle states with ActiveRecord

  • integer : reduce maintainability, do not allow to store many values without a lot of “homemade” helper
  • array (json encoded): allow multiple values but make SQL queries complex (regex..)
  • enum: similar to integer but with rails sugar, do not allow to store many values
  • bitwise: declarative, flexible

Here comes the bitwise

Context

At JobTeaser, every company have the choice to enable many payments modes, in order to publish job offers, let’s call these payment modes:

The problem

How do you handle with enum or basic SQL fields the fact that a company have euros and dollars payments modes enabled?

Our solution

That’s why we built the attr_bitwise library.

class Company < ActiveRecord::Base
include AttrBitwise

attr_bitwise :payment_modes, mapping: [:euros, :dollars, :bitcoins]



end
company = Company.last
company.payment_modes # => [:euros, :dollars]
company.payment_modes_value # => 3
company.payment_mode?(:euros) # => true
company.payment_mode?(:bitcoins) # => false
company.payment_mode == :euros # => false
company.remove_payment_mode(:dollars)
company.payment_mode == :euros # => true
Company.PAYMENT_MODES_MAPPING # => { euros: 1, dollars: 2,
bitcoins: 4 }
class Company < ActiveRecord::Base
include AttrBitwise

attr_bitwise :payment_modes, mapping: [:euros, :dollars, :bitcoins]
scope :with_any_payment_modes, lambda { |*p_sym|
where(
payment_modes_value: bitwise_union(*p_sym, 'payment_modes')
)
}

scope :with_all_payment_modes, lambda { |*p_sym|
where(
payment_modes_value:
bitwise_intersection(*p_sym, 'payment_modes')
)
}
end
# return all companies that have :euros or :dollars as payment modes
Company.with_any_payment_modes(:euros, :dollars).select(:id)

# return all companies that have :euros and :dollars as payment modes
Company.with_all_payment_modes(:euros, :dollars).select(:id)
bitwise_intersection(*mixed_array, column_name)
bitwise_union(*mixed_array, column_name)

--

--

JobTeaser's Engineering Team sharing tips and thoughts about programming

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store