Module: TokenAttribute::ClassMethods

Defined in:
lib/token_attribute.rb

Constant Summary collapse

DEFAULT_TOKEN_LENGTH =
10

Instance Method Summary collapse

Instance Method Details

#token_attribute(*args) ⇒ Object

Macro-ish method to define token-setter. #set_#attribute_name will be defined to set unique token.



14
15
16
17
18
19
20
21
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
# File 'lib/token_attribute.rb', line 14

def token_attribute(*args)
  options = args.extract_options!
  attribute_names = args

  if options[:protected]
    attr_protected *attribute_names
  end

  # `/ 2` because "The length of the result string is twice of n".
  # see: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/securerandom/rdoc/SecureRandom.html#method-c-hex
  raise "Can't set odd number to token length" if options[:length] && (options[:length] % 2) == 1
  length = (options[:length] || DEFAULT_TOKEN_LENGTH) / 2

  attribute_names.each do |attribute|

    generator_method_name = "generate_#{attribute}"
    setter_method_name    = "set_#{attribute}"
    attribute_to_scope    = Array.wrap(options[:scope])

    define_method generator_method_name do
      key = SecureRandom.hex(length)
    end

    define_method setter_method_name do

      candidate = send generator_method_name

      # Gererate scope condition
      condition = {}
      attribute_to_scope.each do |name|
        condition[name] = self.attributes[name]
      end
      condition.merge!(attribute => candidate)

      unless self.class.where(condition).exists?
        self[attribute] = candidate
      else
        # Recur if the token is already used
        send setter_method_name
      end
    end

  end
end