Module: FlagShihTzu::ClassMethods

Defined in:
lib/flag_shih_tzu.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) check_flag(flag, colmn)

Raises:

  • (ArgumentError)


104
105
106
107
# File 'lib/flag_shih_tzu.rb', line 104

def check_flag(flag, colmn)
  raise ArgumentError, "Column name '#{colmn}' for flag '#{flag}' is not a string" unless colmn.is_a?(String)
  raise ArgumentError, "Invalid flag '#{flag}'" if flag_mapping[colmn].nil? || !flag_mapping[colmn].include?(flag)
end

- (Object) has_flags(*args)



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/flag_shih_tzu.rb', line 22

def has_flags(*args)
  flag_hash, opts = parse_options(*args)
  opts = {
    :named_scopes => true,
    :column => DEFAULT_COLUMN_NAME,
    :flag_query_mode => :in_list
  }.update(opts)
  colmn = opts[:column].to_s

  return unless check_flag_column(colmn)

  # options are stored in a class level hash and apply per-column
  self.flag_options ||= {}
  self.flag_options[colmn] = opts

  # the mappings are stored in this class level hash and apply per-column
  self.flag_mapping ||= {}
  self.flag_mapping[colmn] ||= {}

  flag_hash.each do |flag_key, flag_name|
    raise ArgumentError, "has_flags: flag keys should be positive integers, and #{flag_key} is not" unless is_valid_flag_key(flag_key)
    raise ArgumentError, "has_flags: flag names should be symbols, and #{flag_name} is not" unless is_valid_flag_name(flag_name)
    next if flag_mapping[colmn][flag_name] & (1 << (flag_key - 1)) # next if already methods defined by flagshitzu
    raise ArgumentError, "has_flags: flag name #{flag_name} already defined, please choose different name" if method_defined?(flag_name)

    flag_mapping[colmn][flag_name] = 1 << (flag_key - 1)

    class_eval <<-EVAL
      def #{flag_name}
        flag_enabled?(:#{flag_name}, '#{colmn}')
      end

      def #{flag_name}?
        flag_enabled?(:#{flag_name}, '#{colmn}')
      end

      def #{flag_name}=(value)
        FlagShihTzu::TRUE_VALUES.include?(value) ? enable_flag(:#{flag_name}, '#{colmn}') : disable_flag(:#{flag_name}, '#{colmn}')
      end

      def #{flag_name}_changed?
        if colmn_changes = changes['#{colmn}']
          flag_bit = self.class.flag_mapping['#{colmn}'][:#{flag_name}]
          (colmn_changes[0] & flag_bit) != (colmn_changes[1] & flag_bit)
        else
          false
        end
      end

      def self.#{flag_name}_condition(options = {})
        sql_condition_for_flag(:#{flag_name}, '#{colmn}', true, options[:table_alias] || self.table_name)
      end

      def self.not_#{flag_name}_condition
        sql_condition_for_flag(:#{flag_name}, '#{colmn}', false)
      end
    EVAL

    # Define bancg methods when requested
    if flag_options[colmn][:bang_methods]
      class_eval <<-EVAL
        def #{flag_name}!
          enable_flag(:#{flag_name}, '#{colmn}')
        end

        def not_#{flag_name}!
          disable_flag(:#{flag_name}, '#{colmn}')
        end
      EVAL
    end

    # Define the named scopes if the user wants them and AR supports it
    if flag_options[colmn][:named_scopes] && respond_to?(named_scope_method)
      class_eval <<-EVAL
        #{named_scope_method} :#{flag_name}, lambda { { :conditions => #{flag_name}_condition } }
        #{named_scope_method} :not_#{flag_name}, lambda { { :conditions => not_#{flag_name}_condition } }
      EVAL
    end
  end

end