Module: FlagShihTzu

Defined in:
lib/flag_shih_tzu.rb,
lib/flag_shih_tzu/version.rb

Defined Under Namespace

Modules: ClassMethods, Version Classes: BooleanEncoder, Configuration, DuplicateFlagColumnException, IncorrectFlagColumnException, InvalidFlagValueException, NoSuchFlagException, NoSuchFlagQueryModeException, TriStateEncoder

Constant Summary collapse

TRUE_VALUES =

taken from ActiveRecord::ConnectionAdapters::Column

[true, 1, "1", "t", "T", "true", "TRUE"]
FALSE_VALUES =
[false, 0, "0", "f", "F", "false", "FALSE"]
NIL_VALUES =
[nil, "", "nil", "NULL", "null"]
DEFAULT_COLUMN_NAME =
"flags"
DEFAULT_CHECK_FOR_COLUMN =
false
DEFAULT_FLAG_QUERY_MODE =
:bit_operator
DEFAULT_VALUE_MODE =
:boolean
DEFAULT_BIT_WIDTH =
1
FLAG_ADAPTER_CLASS_NAMES =
{
  "mysql" => "Mysql2Adapter",
  "mysql2" => "Mysql2Adapter",
  "postgis" => "PostgreSQLAdapter",
  "postgresql" => "PostgreSQLAdapter",
  "sqlite" => "SQLite3Adapter",
  "sqlite3" => "SQLite3Adapter",
  "trilogy" => "TrilogyAdapter",
}.freeze
FLAG_ADAPTER_REQUIRE_NAMES =
{
  "mysql" => "mysql2",
  "postgis" => "postgresql",
}.freeze
FLAG_COLUMN_ONLY_ASSIGNMENT_ADAPTERS =
["jdbcsqlite3", "postgis", "postgresql", "sqlite", "sqlite3"].freeze
CONFIGURATION =
Configuration.new
VERSION =

Traditional Constant Location

Version::VERSION

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_check_for_columnObject



53
54
55
# File 'lib/flag_shih_tzu.rb', line 53

def default_check_for_column
  CONFIGURATION.default_check_for_column
end

.default_check_for_column=(value) ⇒ Object



57
58
59
# File 'lib/flag_shih_tzu.rb', line 57

def default_check_for_column=(value)
  CONFIGURATION.default_check_for_column = value
end

.default_flag_query_modeObject



61
62
63
# File 'lib/flag_shih_tzu.rb', line 61

def default_flag_query_mode
  CONFIGURATION.default_flag_query_mode
end

.default_flag_query_mode=(value) ⇒ Object



65
66
67
# File 'lib/flag_shih_tzu.rb', line 65

def default_flag_query_mode=(value)
  CONFIGURATION.default_flag_query_mode = value
end

.included(base) ⇒ Object



46
47
48
49
50
51
# File 'lib/flag_shih_tzu.rb', line 46

def included(base)
  base.extend(ClassMethods)
  base.class_attribute(:flag_options) unless defined?(base.flag_options)
  base.class_attribute(:flag_mapping) unless defined?(base.flag_mapping)
  base.class_attribute(:flag_columns) unless defined?(base.flag_columns)
end

Instance Method Details

#all_flags(colmn = DEFAULT_COLUMN_NAME) ⇒ Object



887
888
889
# File 'lib/flag_shih_tzu.rb', line 887

def all_flags(colmn = DEFAULT_COLUMN_NAME)
  flag_mapping[colmn].keys
end

#as_flag_collection(colmn = DEFAULT_COLUMN_NAME, *args) ⇒ Object

Use with a checkbox form builder, like rails’ or simple_form’s :selected_flags, used in the example below, is a method defined

by flag_shih_tzu for bulk setting flags like this:

  form_for @user do |f|
    f.collection_check_boxes(:selected_flags,
      f.object.as_flag_collection("flags",
          :sent_warm_up_email,
          :not_follow_up_called),
      :first,
      :last)
  end


975
976
977
978
979
980
# File 'lib/flag_shih_tzu.rb', line 975

def as_flag_collection(colmn = DEFAULT_COLUMN_NAME, *args)
  flags_to_collect = args.empty? ? all_flags(colmn) : args
  collect_flags(*flags_to_collect) do |memo, flag|
    memo << [flag, flag_enabled?(flag, colmn)]
  end
end

#attributes_with_flagsObject



992
993
994
995
996
# File 'lib/flag_shih_tzu.rb', line 992

def attributes_with_flags
  flags_as_attributes.each_with_object(attributes.dup) do |(flag, enabled), attrs|
    attrs[flag.to_s] = enabled
  end
end

#chained_flags_with_signature(colmn = DEFAULT_COLUMN_NAME, *args) ⇒ Object

Use with chained_flags_with to find records with specific flags

set to the same values as on this record.

For a record that has sent_warm_up_email = true and the other flags false:

user.chained_flags_with_signature
=> [:sent_warm_up_email,
    :not_follow_up_called,
    :not_sent_final_email,
    :not_scheduled_appointment]
User.chained_flags_with("flags", *user.chained_flags_with_signature)
=> the set of Users that have the same flags set as user.


950
951
952
953
954
955
956
957
958
959
960
# File 'lib/flag_shih_tzu.rb', line 950

def chained_flags_with_signature(colmn = DEFAULT_COLUMN_NAME, *args)
  flags_to_collect = args.empty? ? all_flags(colmn) : args
  truthy_and_chosen =
    selected_flags(colmn)
      .select { |flag| flags_to_collect.include?(flag) }
  truthy_and_chosen.concat(
    collect_flags(*flags_to_collect) do |memo, flag|
      memo << "not_#{flag}".to_sym unless truthy_and_chosen.include?(flag)
    end,
  )
end

#clear_flag(flag, colmn = nil) ⇒ Object

Performs the bitwise operation so the flag will return nil when supported.



847
848
849
850
851
852
# File 'lib/flag_shih_tzu.rb', line 847

def clear_flag(flag, colmn = nil)
  colmn = determine_flag_colmn_for(flag) if colmn.nil?
  self.class.check_flag(flag, colmn)

  set_flag_value(flag, nil, colmn)
end

#disable_flag(flag, colmn = nil) ⇒ Object

Performs the bitwise operation so the flag will return false.



839
840
841
842
843
844
# File 'lib/flag_shih_tzu.rb', line 839

def disable_flag(flag, colmn = nil)
  colmn = determine_flag_colmn_for(flag) if colmn.nil?
  self.class.check_flag(flag, colmn)

  set_flag_value(flag, false, colmn)
end

#enable_flag(flag, colmn = nil) ⇒ Object

Performs the bitwise operation so the flag will return true.



831
832
833
834
835
836
# File 'lib/flag_shih_tzu.rb', line 831

def enable_flag(flag, colmn = nil)
  colmn = determine_flag_colmn_for(flag) if colmn.nil?
  self.class.check_flag(flag, colmn)

  set_flag_value(flag, true, colmn)
end

#flag_disabled?(flag, colmn = nil) ⇒ Boolean

Returns:

  • (Boolean)


861
862
863
864
865
866
# File 'lib/flag_shih_tzu.rb', line 861

def flag_disabled?(flag, colmn = nil)
  colmn = determine_flag_colmn_for(flag) if colmn.nil?
  self.class.check_flag(flag, colmn)

  flag_encoder_for_column(colmn).disabled_value(flags(colmn), self.class.flag_mapping[colmn][flag])
end

#flag_enabled?(flag, colmn = nil) ⇒ Boolean

Returns:

  • (Boolean)


854
855
856
857
858
859
# File 'lib/flag_shih_tzu.rb', line 854

def flag_enabled?(flag, colmn = nil)
  colmn = determine_flag_colmn_for(flag) if colmn.nil?
  self.class.check_flag(flag, colmn)

  flag_encoder_for_column(colmn).read(flags(colmn), self.class.flag_mapping[colmn][flag])
end

#flags(colmn = DEFAULT_COLUMN_NAME) ⇒ Object



868
869
870
# File 'lib/flag_shih_tzu.rb', line 868

def flags(colmn = DEFAULT_COLUMN_NAME)
  self[colmn] || 0
end

#flags=(value) ⇒ Object



872
873
874
# File 'lib/flag_shih_tzu.rb', line 872

def flags=(value)
  set_flags(value)
end

#flags_as_attributes(colmn = nil, *args) ⇒ Object



982
983
984
985
986
987
988
989
990
# File 'lib/flag_shih_tzu.rb', line 982

def flags_as_attributes(colmn = nil, *args)
  columns = colmn.nil? ? self.class.flag_columns : [colmn]
  columns.each_with_object({}) do |column, memo|
    flags_to_collect = args.empty? ? all_flags(column) : args
    flags_to_collect.each do |flag|
      memo[flag] = flag_enabled?(flag, column)
    end
  end
end

#has_flag?(colmn = DEFAULT_COLUMN_NAME) ⇒ Boolean

Returns:

  • (Boolean)


915
916
917
# File 'lib/flag_shih_tzu.rb', line 915

def has_flag?(colmn = DEFAULT_COLUMN_NAME)
  !selected_flags(colmn).empty?
end

#select_all_flags(colmn = DEFAULT_COLUMN_NAME) ⇒ Object



903
904
905
906
907
# File 'lib/flag_shih_tzu.rb', line 903

def select_all_flags(colmn = DEFAULT_COLUMN_NAME)
  all_flags(colmn).each do |flag|
    enable_flag(flag, colmn)
  end
end

#selected_flags(colmn = DEFAULT_COLUMN_NAME) ⇒ Object



891
892
893
894
895
# File 'lib/flag_shih_tzu.rb', line 891

def selected_flags(colmn = DEFAULT_COLUMN_NAME)
  all_flags(colmn)
    .map { |flag_name| send(flag_name) ? flag_name : nil }
    .compact
end

#selected_flags=(chosen_flags) ⇒ Object

Useful for a form builder use selected_#column= for custom column names.



899
900
901
# File 'lib/flag_shih_tzu.rb', line 899

def selected_flags=(chosen_flags)
  set_selected_flags(chosen_flags, DEFAULT_COLUMN_NAME)
end

#set_flags(value, colmn = DEFAULT_COLUMN_NAME) ⇒ Object



876
877
878
879
880
881
882
883
884
885
# File 'lib/flag_shih_tzu.rb', line 876

def set_flags(value, colmn = DEFAULT_COLUMN_NAME)
  case value
  when Array
    set_selected_flags(value, colmn)
  when Hash
    set_flag_attributes(value, colmn)
  else
    self[colmn] = value
  end
end

#unselect_all_flags(colmn = DEFAULT_COLUMN_NAME) ⇒ Object



909
910
911
912
913
# File 'lib/flag_shih_tzu.rb', line 909

def unselect_all_flags(colmn = DEFAULT_COLUMN_NAME)
  all_flags(colmn).each do |flag|
    disable_flag(flag, colmn)
  end
end

#update_flag!(flag, value, update_instance = false) ⇒ Object

returns true if successful third parameter allows you to specify that ‘self` should

also have its in-memory flag attribute updated.


922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
# File 'lib/flag_shih_tzu.rb', line 922

def update_flag!(flag, value, update_instance = false)
  flag_value = normalized_flag_value(value, determine_flag_colmn_for(flag.to_sym))
  sql = self.class.set_flag_sql(flag.to_sym, flag_value)
  if update_instance
    set_flag_value(flag.to_sym, flag_value)
  end
  if ActiveRecord::VERSION::MAJOR <= 3
    self.class
      .update_all(sql, self.class.primary_key => id) == 1
  else
    self.class
      .where("#{self.class.primary_key} = ?", id)
      .update_all(sql) == 1
  end
end