Module: SimpleSet::ClassMethods
- Defined in:
- lib/simple_set.rb
Instance Method Summary collapse
-
#as_set(set_cd, values, options = {}) ⇒ Object
Provides ability to create simple sets based on hashes or arrays, backed by integer columns (but not limited to integer columns).
Instance Method Details
#as_set(set_cd, values, options = {}) ⇒ Object
Provides ability to create simple sets based on hashes or arrays, backed by integer columns (but not limited to integer columns).
Columns are supposed to be suffixed by _cd, if not, use :column => 'the_column_name', so some example migrations:
add_column :users, :roles_cd, :integer
add_column :users, :permissions, :integer # and a custom column...
and then in your model:
class User
as_set :roles, [:management, :accounting]
end
# or use a hash:
class User
as_set :user_permissions, { create_invoice: 1, send_invoice: 2, create_user: 4, all: 7 }, column: 'permissions'
end
Now it’s possible to access the set and the internally stored value like:
john_doe = User.new
john_doe.roles #=> []
john_doe.roles = [:accounting]
john_doe.roles #=> [:accounting]
john_doe.roles_cd #=> 2
And to make life a tad easier: a few shortcut methods to work with the set are also created.
john_doe.accounting? #=> true
john_doe.accounting = false
john_doe.accounting? #=> false
Configuration options:
-
:column- Specifies a custom column name, instead of the default suffixed_cdcolumn. -
:prefix- Define a prefix, which is prefixed to the shortcut methods (e.g.<symbol>=and<symbol>?), if it’s set totruethe enumeration name is used as a prefix, else a custom prefix (symbol or string) (default isnil=> no prefix) -
:slim- If set totrueno shortcut methods for all enumeration values are being generated, if set to:classonly class-level shortcut methods are disabled (default isnil=> they are generated) -
:whiny- Boolean value which if set totruewill throw anArgumentErrorif an invalid value is passed to the setter (e.g. a value for which no enumeration exists). if set tofalseno exception is thrown and the internal value is left untouched (default istrue)
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/simple_set.rb', line 75 def as_set(set_cd, values, = {}) = SimpleSet..merge({column: "#{set_cd}_cd"}).merge() .assert_valid_keys(:column, :prefix, :slim, :whiny) = (class << self; self; end) values = SimpleSet::SetHash.new(values) define_method("#{set_cd}") do current = send([:column]) return nil if current.nil? values.select { |k,v| v == current & v }.keys end define_method("#{set_cd}=") do |new_values| real = nil if ! new_values.nil? then new_values = new_values.reject { |x| x == ''}.collect { |x| x.to_sym } real = new_values.collect do |k| if values.has_key?(k) then values[k] else raise(ArgumentError, "Invalid set value : #{k}") if [:whiny] 0 end end.inject(:|) end send("#{[:column]}=", real) end .send :define_method, "#{set_cd}" do return values.keys end if [:slim] != true then prefix = [:prefix] && "#{[:prefix] == true ? set_cd.to_s.singularize : [:prefix]}_" values.each do |k,code| sym = SetHash.symbolize(k) define_method("#{prefix}#{sym}?") do current = send([:column]) || 0 code == (code & current) end define_method("#{prefix}#{sym}=") do |value| current = send([:column]) || 0 if value then current |= code else current &= ~code end send("#{[:column]}=", current) code == (current & code) end unless [:slim] == :class then .send(:define_method, "#{prefix}#{sym}", Proc.new { |*args| args.first ? k : code }) end end end end |