• Stars
    star
    221
  • Rank 179,773 (Top 4 %)
  • Language
    Ruby
  • Created over 14 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

n Booleans = 1 Integer, saves columns and migrations.

Save migrations and columns by storing multiple booleans in a single integer.
e.g. true-false-false = 1, false-true-false = 2, true-false-true = 5 (1,2,4,8,..)

class User < ActiveRecord::Base
  include Bitfields
  bitfield :my_bits, 1 => :seller, 2 => :insane, 4 => :sensible
end

user = User.new(seller: true, insane: true)
user.seller # => true
user.sensible? # => false
user.my_bits # => 3
  • records bitfield_changes user.bitfield_changes # => {"seller" => [false, true], "insane" => [false, true]} (also seller_was / seller_change / seller_changed? / seller_became_true? / seller_became_false?)
    • Individual added methods (i.e, seller_was, seller_changed?, etc..) can be deactivated with bitfield ..., added_instance_methods: false
    • Note: ActiveRecord 5.2 changes the behavior of _was and _changed? methods when used in the context of an after_save callback.
      • ActiveRecord 5.1 will use the use the values that were just changed.
      • ActiveRecord 5.2, however, will return the current value for _was and false for _changed? since the previous changes have been persisted.
  • adds scopes User.seller.sensible.first (deactivate with bitfield ..., scopes: false)
  • builds sql User.bitfield_sql(insane: true, sensible: false) # => '(users.my_bits & 6) = 1'
  • builds sql with OR condition User.bitfield_sql({ insane: true, sensible: true }, query_mode: :bit_operator_or) # => '(users.my_bits & 2) = 2 OR (users.bits & 4) = 4'
  • builds index-using sql with bitfield ... , query_mode: :in_list and User.bitfield_sql(insane: true, sensible: false) # => 'users.my_bits IN (2, 3)' (2 and 1+2) often slower than :bit_operator sql especially for high number of bits
  • builds update sql User.set_bitfield_sql(insane: true, sensible: false) == 'my_bits = (my_bits | 6) - 4'
  • faster sql than any other bitfield lib through combination of multiple bits into a single sql statement
  • gives access to bits User.bitfields[:my_bits][:sensible] # => 4
  • converts hash to bits User.bitfield_bits(seller: true) # => 1

Install

gem install bitfields

Migration

ALWAYS set a default, bitfield queries will not work for NULL

t.integer :my_bits, default: 0, null: false
# OR
add_column :users, :my_bits, :integer, default: 0, null: false

Instance Methods

Global Bitfield Methods

Method Name Example (user = User.new(seller: true, insane: true) Result
bitfield_values user.bitfield_values {"seller" => true, "insane" => true, "sensible" => false}
bitfield_changes user.bitfield_changes {"seller" => [false, true], "insane" => [false, true]}

Individual Bit Methods

Model Getters / Setters

Method Name Example (user = User.new) Result
#{bit_name} user.seller false
#{bit_name}= user.seller = true true
#{bit_name}? user.seller? true

Dirty Methods:

Some, not all, ActiveRecord::AttributeMethods::Dirty and ActiveModel::Dirty methods can be used on each bitfield:

Before Model Persistence
Method Name Example (user = User.new) Result
#{bit_name}_was user.seller_was false
#{bit_name}_in_database user.seller_in_database false
#{bit_name}_change user.seller_change [false, true]
#{bit_name}_change_to_be_saved user.seller_change_to_be_saved [false, true]
#{bit_name}_changed? user.seller_changed? true
will_save_change_to_#{bit_name}? user.will_save_change_to_seller? true
#{bit_name}_became_true? user.seller_became_true? true
#{bit_name}_became_false? user.seller_became_false? false
After Model Persistence
Method Name Example (user = User.create(seller: true)) Result
#{bit_name}_before_last_save user.seller_before_last_save false
saved_change_to_#{bit_name} user.saved_change_to_seller [false, true]
saved_change_to_#{bit_name}? user.saved_change_to_seller? true
  • Note: These methods are dynamically defined for each bitfield, and function separately from the real ActiveRecord::AttributeMethods::Dirty/ActiveModel::Dirty methods. As such, generic methods (e.g. attribute_before_last_save(:attribute)) will not work.

Examples

Update all users

User.seller.not_sensible.update_all(User.set_bitfield_sql(seller: true, insane: true))

Delete the shop when a user is no longer a seller

before_save :delete_shop, if: -> { |u| u.seller_change == [true, false] }

List fields and their respective values

user = User.new(insane: true)
user.bitfield_values(:my_bits) # => { seller: false, insane: true, sensible: false }

TIPS

  • [Upgrading] in version 0.2.2 the first field(when not given as hash) used bit 2 -> add a bogus field in first position
  • [Defaults for new records] set via db migration or name the bit foo_off to avoid confusion, setting via after_initialize does not work
  • It is slow to do: #{bitfield_sql(...)} AND #{bitfield_sql(...)}, merge both into one hash
  • bit_operator is faster in most cases, use query_mode: :in_list sparingly
  • Standard mysql integer is 4 byte -> 32 bitfields
  • If you are lazy or bad at math you can also do bitfields :bits, :foo, :bar, :baz
  • If you are want more readability and reduce clutter you can do bitfields 2**0 => :foo, 2**1 => :bar, 2**32 => :baz

Query-mode Benchmark

The query_mode: :in_list is slower for most queries and scales miserably with the number of bits.
Stay with the default query-mode. Only use :in_list if your edge-case shows better performance.

performance

Testing With RSpec

To assert that a specific flag is a bitfield flag and has the active?, active, and active= methods and behavior use the following matcher:

require 'bitfields/rspec'

describe User do
  it { should have_a_bitfield :active }
end

TODO

  • convenient named scope User.with_bitfields(xxx: true, yyy: false)

Authors

Michael Grosser
[email protected]
License: MIT
Build Status

More Repositories

1

parallel

Ruby: parallel processing made simple and fast
Ruby
4,052
star
2

parallel_tests

Ruby: 2 CPUs = 2x Testing Speed for RSpec, Test::Unit and Cucumber
Ruby
3,257
star
3

pru

Pipeable Ruby - forget about grep / sed / awk / wc ... use pure, readable Ruby!
Ruby
579
star
4

smusher

Ruby/CLI: Automatic lossless reduction of all your images
Ruby
555
star
5

maxitest

Minitest + all the features you always wanted.
Ruby
441
star
6

fast_gettext

Ruby GetText, but 12x faster + 530x less garbage + simple + clean namespace + threadsafe + extendable + multiple backends
Ruby
390
star
7

wwtd

WWTD: Travis simulator - faster + no more waiting for build emails
Ruby
366
star
8

rspec-instafail

Show failing specs instantly
Ruby
272
star
9

gettext_i18n_rails

Rails: FastGettext, I18n integration -- simple, threadsafe and fast!
Ruby
257
star
10

test_after_commit

Make after_commit callbacks fire in tests for Rails 3+ with transactional_fixtures = true.
Ruby
240
star
11

rpx_now

Ruby: RPXNow.com user login/creation and view helpers Facebook, Twitter, Google, MSN, OpenID, MySpace, Yahoo -- All in One
Ruby
230
star
12

single_cov

Actionable code coverage.
Ruby
226
star
13

i18n_data

Ruby: country/language names and 2-letter-code pairs, in 85 languages, for country/language i18n
Ruby
186
star
14

vendorer

Vendorer keeps your dependencies documented, cached and up to date
Ruby
186
star
15

ar_after_transaction

Execute irreversible actions only when transactions are not rolled back
Ruby
155
star
16

url_store

Data securely stored in urls.
Ruby
146
star
17

kennel

Datadog monitors/dashboards/slos as code, avoid chaotic management via UI
Ruby
129
star
18

ruco

Desktop-style, Intuitive, Commandline Editor in Ruby. "Better than nano, simpler than vim."
Ruby
125
star
19

programming_pearls

eBook: Programming Pearls Rewritten in Ruby
Ruby
108
star
20

easy_esi

Rails: Cached pages with updated partials
Ruby
106
star
21

reduce

Ruby/CLI: minify javascript + stylesheets, lossless image optimization
JavaScript
90
star
22

git-autobisect

Find the first broken commit without having to learn git bisect
Ruby
84
star
23

parallel_split_test

Split a big test file into multiple chunks and run them in parallel
Ruby
81
star
24

tic_tac_toe

Play Tic-Tac-Toe in Ruby using Curses(full-screen-commandline app)
Ruby
71
star
25

sort_alphabetical

Ruby: sort UTF8 Strings alphabetical via Enumerable extension
Ruby
69
star
26

soft_deletion

Explicit soft deletion for ActiveRecord via deleted_at and default scope
Ruby
68
star
27

youtube_search

Search youtube via this simple ruby api
Ruby
67
star
28

simple_auto_complete

Rails: Simple, customizable, unobstrusive - Autocomplete
JavaScript
64
star
29

dispel

Ruby: Remove evil curses
Ruby
63
star
30

preoomkiller

Softly kills your process with SIGTERM before it runs out of memory.
Ruby
63
star
31

single_test

Rake tasks to invoke single tests/specs with rakish syntax
Ruby
60
star
32

dotfiles

Clean and powerful dotfiles -- bash / git / ruby / irb / nano / ruco
Shell
57
star
33

bundler-organization_audit

Automatic Gemfile security audit for all your organizaition/user repos
Ruby
52
star
34

fallback

Fallback when original attribute is not present or somethings not right.
Ruby
47
star
35

record_activities

Rails: Record user activities without controller helpers, build on top of userstamps plugin
Ruby
47
star
36

ie_iframe_cookies

Rails: Normal cookies inside IFrames for IE via P3P headers
Ruby
45
star
37

cachy

Ruby: Caching library to simplify and organize caching
Ruby
44
star
38

zombie_passenger_killer

Guaranteed zombie passengers death.
Ruby
44
star
39

tracked_plugins

script/plugin now keeps track of installation, can list urls/revisions/install-dates/plugin-locally-hacked? and update.
Ruby
43
star
40

stub_server

Boot up a real server to serve testing replies
Ruby
43
star
41

rails2_asset_pipeline

Familiar asset handling for those stuck on Rails 2
Ruby
41
star
42

request_recorder

Record your rack/rails requests and store them for future inspection
Ruby
40
star
43

ar_merge

Merge 2 ActiveRecords, preserving attributes, associations and counters
Ruby
40
star
44

gem-dependent

How many gems depend on your gem ?
Ruby
39
star
45

travis_dedup

Stop all builds on the same PR when a new job starts
Ruby
38
star
46

safe_regexp

Ruby Regex Timeout / Backtracking Bomb Safety
Ruby
30
star
47

translation_db_engine

Rails/AR: engine to manage translations inside a database
Ruby
30
star
48

rubinjam

Covert ruby gem to universal cross-platform binary
Ruby
30
star
49

gettext_i18n_rails_example

Rails example application using FastGettext + gettext_i18n_rails + gettext_test_log
Ruby
29
star
50

url_to_media_tag

Convert an Youtube/Vimeo/Image... Url to image or video embed.
Ruby
27
star
51

forking_test_runner

Run every test in a fork to avoid pollution and get clean output per test
Ruby
27
star
52

restful_catch_all_route

One rule for complete restful routing, no helpers, no worries.
Ruby
26
star
53

scopify

Add named scopes and chainable scopes to any Object / Model.
Ruby
24
star
54

key_value

Abuse Sql database as Key-Value Store
Ruby
22
star
55

acts_as_feed

Rails/AR: Transform a Model into a Feed Representation (Feed Reader)
Ruby
22
star
56

sinatra-magick

Sinatra app to manipulate images given by url via mini_magick and image_magick. completly evented
Ruby
22
star
57

concern

Ruby: Seperation of concerns without meta-madness and namespace pollution.
Ruby
22
star
58

has_a_location

AR: Easy location (lat/long) handling + in_radius + find on a given map section
Ruby
22
star
59

virtual_asset_path

Improve Rails Asset Caching with MD5 and virtual folders
Ruby
21
star
60

s3_slider

jQuery: slideshow displaying images + description, ~1kb for js+css, simple and elegant
HTML
21
star
61

git-whence

Find the merge and pull request a commit came from + fuzzy search for cherry-picks
Ruby
21
star
62

readable_random

Ruby: Readable random strings for coupons or tokens
Ruby
20
star
63

testrbl

Run ruby Minitest/Test::Unit/Spec/Shoulda tests by line-number / files / folder
Ruby
20
star
64

s3_meta_sync

Efficiently sync folders with s3 using a metadata file with md5 sums.
Ruby
20
star
65

countries_and_languages

Rails: Countries and languages in I18n.locale for select_tag or output in 85 languages
Ruby
19
star
66

autoscaling

Amazon AWS/EC2 autoscaling All in one
Shell
19
star
67

helpful_fields

Simple & Helpful Field Helpers for Rails e.g. check_box_with_label or prefilled fields from params
Ruby
18
star
68

go-testcov

`go test` that fails on uncovered lines and shows them
Go
18
star
69

cleanser

Find polluting test by bisecting your tests.
Ruby
17
star
70

repo_dependency_graph

Graph the dependencies of your repositories
Ruby
16
star
71

get_pomo

Ruby/Gettext: A .mo and .po file parser/generator
Ruby
16
star
72

honeypot

Rails: Simple honeypots
Ruby
16
star
73

random_records

Rails/AR: Fast random records for ActiveRecord
Ruby
16
star
74

rpx_now_example

Example Rails app using RPXNow plugin
Ruby
16
star
75

logrecycler

Re-process logs from applications you cannot modify to convert them to json and add prometheus/stats metrics
Go
15
star
76

after_commit_exception_notification

Rails: Get notified when an after_commit block blows up
Ruby
15
star
77

textpow

Read TextMate syntax files and parse text with them
Ruby
14
star
78

codeclimate_batch

Report a batch of codeclimate results by merging and from multiple servers
Ruby
13
star
79

dockerb

Dockerfile.erb - use ruby in your dynamic Dockerfile
Ruby
12
star
80

cia

Central Internal Auditing: Audit model events like update/create/delete + attribute changes + grouped them by transaction, in normalized table layout for easy query access.
Ruby
12
star
81

cc-amend

Unify reports from all your tests runs and send them as one.
Ruby
12
star
82

gem_of_thrones

Everybody wants to be king, but only one can rule (synchronized via a distributed cache)
Ruby
12
star
83

github-grep

Grep through github search results
Ruby
11
star
84

kube-leader

Simple Kubernetes Leader Election via ConfigMap as ENTRYPOINT
Go
10
star
85

travis_cron

Run travis as cron (also supports travis PRO)
Ruby
10
star
86

air_man

Email notifications for high-frequency Airbrake errors
Ruby
10
star
87

i18n-backend-http

Rails I18n Backend for Http APIs with etag-aware distributed background polling and lru-memory+[memcache] caching.
Ruby
9
star
88

gem_on_demand

Run your own gem server that fetches from github, uses tags as version and builds gems on demand
Ruby
9
star
89

matching_bundle

Find a matching bundler version for a Gemfile and use it
Ruby
9
star
90

active_record-comments

Add comments to ActiveRecord queries to see where they came from or what user caused them
Ruby
9
star
91

translated_attributes

AR/Rails translatable attributes through virtual fields
Ruby
9
star
92

cmd2json

Covert command output and exit status to json to pipe them atomically into logs
Ruby
8
star
93

autolang

Automatic translation to a new language for Gettext/JSON using Google translate
Ruby
8
star
94

db_graph

Easy graphs from AR date fields
Ruby
8
star
95

organization_license_audit

Audit all licenses used by your github organization/user
Ruby
8
star
96

ruby-cli-daemon

Make all gem executables execute instantly
Ruby
8
star
97

ar_multi_threaded_transactional_tests

Execute multithreaded code while still using transactional fixtures by synchronizing db access to a single connection
Ruby
8
star
98

rhr

Ruby Hypertext Refinement -- the ease of PHP with the elegance of Ruby
Ruby
7
star
99

git-graph

Date porn from your git history
Ruby
7
star
100

unicorn_wrangler

Unicorn: out of band GC / restart on max memory bloat / restart after X requests
Ruby
7
star