virtual-attributes 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +2 -0
- data/LICENSE +22 -0
- data/lib/virtual-attributes.rb +13 -0
- data/lib/virtual-attributes/base.rb +7 -0
- data/lib/virtual-attributes/base/attributes.rb +39 -0
- data/lib/virtual-attributes/base/casts.rb +39 -0
- data/lib/virtual-attributes/base/conversions.rb +24 -0
- data/lib/virtual-attributes/base/defaults.rb +21 -0
- data/lib/virtual-attributes/base/validations.rb +9 -0
- data/lib/virtual-attributes/serialization.rb +43 -0
- data/spec/base_spec.rb +160 -0
- data/spec/serialization_spec.rb +60 -0
- data/spec/spec_helper.rb +10 -0
- data/virtual-attributes.gemspec +18 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c4254b8bcb72697664cc7d0770e7a7d9ad80cc89
|
4
|
+
data.tar.gz: 2486a778c6ef88d55c635b5f333d4fa6796cee86
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6f3a8f1bc69509b641619878ce1dc43e976a9b52712cd9e17684633fa6b10b350da3abb84fa932d9f4fed6af9e8349ca1c96ffcf636341fe3b8afe539d0f0595
|
7
|
+
data.tar.gz: f91098c4691b063c1439698b90169234bc244282860f66e4130ec0931ba0b2caa0908055c491db23813d4157bd9bab3a05debdee681d7af788ce510aa388d92f
|
data/.rspec
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Ihcène Med.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class VirtualAttributes
|
2
|
+
end
|
3
|
+
|
4
|
+
require 'virtual-attributes/base/attributes'
|
5
|
+
require 'virtual-attributes/base/casts'
|
6
|
+
require 'virtual-attributes/base/conversions'
|
7
|
+
require 'virtual-attributes/base/defaults'
|
8
|
+
require 'virtual-attributes/base/validations'
|
9
|
+
require 'virtual-attributes/base'
|
10
|
+
|
11
|
+
require 'virtual-attributes/serialization'
|
12
|
+
|
13
|
+
ActiveRecord::Base.singleton_class.send :include, VirtualAttributes::Serialization::ClassMethods
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class VirtualAttributes::Base
|
2
|
+
module Attributes
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :columns
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(attrs = {})
|
10
|
+
attrs.each_pair do |k, v|
|
11
|
+
send "#{k}=", v
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def read_attribute(column)
|
16
|
+
instance_variable_get("@#{column}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_attribute(column, value)
|
20
|
+
instance_variable_set "@#{column}", value
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def column(name, options = {})
|
25
|
+
(self.columns ||= {})[name] = {
|
26
|
+
options: options.with_indifferent_access
|
27
|
+
}
|
28
|
+
|
29
|
+
define_method name do
|
30
|
+
read_attribute(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
define_method :"#{name}=" do |value|
|
34
|
+
write_attribute(name, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class VirtualAttributes::Base
|
2
|
+
module Casts
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
TYPES = ActiveRecord::Type::Value.subclasses.map{ |k| k.name.split('::').last.underscore.to_sym }
|
6
|
+
|
7
|
+
def write_attribute(column, value)
|
8
|
+
super column, cast_type(column, value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def cast_type(column, value)
|
12
|
+
self.class.columns[column][:castor].send(:cast_value, value)
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def column(name, type, options = {})
|
17
|
+
raise ArgumentError unless type.to_sym.in? TYPES
|
18
|
+
|
19
|
+
super(name, options)
|
20
|
+
|
21
|
+
self.columns[name.to_sym][:type] = type.to_sym,
|
22
|
+
self.columns[name.to_sym][:castor] =
|
23
|
+
ActiveRecord::Type.const_get(type.to_s.classify)
|
24
|
+
.new(options.symbolize_keys
|
25
|
+
.slice(:precision, :scale, :limit))
|
26
|
+
end
|
27
|
+
|
28
|
+
TYPES.each do |type|
|
29
|
+
define_method type do |*args|
|
30
|
+
options = args.extract_options!
|
31
|
+
|
32
|
+
args.each do |column_name|
|
33
|
+
column column_name, type, options
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class VirtualAttributes::Base
|
2
|
+
module Conversions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def wrap(val)
|
7
|
+
case val
|
8
|
+
when Hash
|
9
|
+
new(val)
|
10
|
+
when String
|
11
|
+
val.blank? ? new({}) : raise(ArgumentError('String is not convertible to #{self.name}'))
|
12
|
+
when self
|
13
|
+
val
|
14
|
+
when NilClass
|
15
|
+
new({})
|
16
|
+
when OpenStruct
|
17
|
+
new val.to_h
|
18
|
+
else
|
19
|
+
raise ArgumentError.new("#{val.class.name} is not convertible to #{self.name}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class VirtualAttributes::Base
|
2
|
+
module Defaults
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def read_attribute(column)
|
6
|
+
val = super
|
7
|
+
val.nil? ? default_value(column) : val
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def default_value(column)
|
12
|
+
default = self.class.columns[column][:options][:default]
|
13
|
+
|
14
|
+
if default
|
15
|
+
cast_type(
|
16
|
+
column,
|
17
|
+
default.respond_to?(:call) ? default.call(self) : default)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module VirtualAttributes::Serialization
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
def serialize(*args, &block)
|
6
|
+
if block_given?
|
7
|
+
attr_name = args.first.to_s.presence || raise(ArgumentError.new('Attr name is mandatory'))
|
8
|
+
klass_name = "#{attr_name.classify}VirtualAttributes"
|
9
|
+
|
10
|
+
klass = Class.new VirtualAttributes::Base
|
11
|
+
const_set klass_name, klass
|
12
|
+
|
13
|
+
yield const_get klass_name
|
14
|
+
|
15
|
+
super attr_name, const_get(klass_name)
|
16
|
+
|
17
|
+
validates attr_name, virtual_attributes: true
|
18
|
+
|
19
|
+
define_method :"#{attr_name}=" do |val|
|
20
|
+
super self.class.const_get(klass_name).wrap(val)
|
21
|
+
end
|
22
|
+
|
23
|
+
define_method :"#{attr_name}" do
|
24
|
+
val = super()
|
25
|
+
val.is_a?(self.class.const_get(klass_name)) ? val : self.class.const_get(klass_name).wrap(val)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
super(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ::VirtualAttributesValidator < ActiveModel::EachValidator
|
33
|
+
def validate_each(record, attribute, value)
|
34
|
+
return unless value.is_a?(VirtualAttributes::Base::Validations)
|
35
|
+
|
36
|
+
if value.invalid?
|
37
|
+
record.errors[attribute] << value.errors.full_messages.join('. ')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe VirtualAttributes::Base do
|
4
|
+
describe "Accessors" do
|
5
|
+
it "should define accessors" do
|
6
|
+
klass = Class.new(VirtualAttributes::Base) do
|
7
|
+
string :username
|
8
|
+
end
|
9
|
+
|
10
|
+
instance = klass.new
|
11
|
+
expect(instance).to respond_to :username
|
12
|
+
expect(instance).to respond_to(:'username=').with(1).argument
|
13
|
+
|
14
|
+
instance.username = 'John'
|
15
|
+
expect(instance.username).to eql('John')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should allow defining several attributes at once" do
|
19
|
+
klass = Class.new(VirtualAttributes::Base) do
|
20
|
+
string :firstname, :lastname
|
21
|
+
end
|
22
|
+
instance = klass.new
|
23
|
+
|
24
|
+
expect(instance).to respond_to :firstname, :lastname
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "Type casts" do
|
29
|
+
before(:each) do
|
30
|
+
@klass = Class.new(VirtualAttributes::Base) do
|
31
|
+
string :username
|
32
|
+
date :birthdate
|
33
|
+
boolean :rockstar
|
34
|
+
integer :age
|
35
|
+
end
|
36
|
+
@instance = @klass.new
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should cast dates correctly" do
|
40
|
+
@instance.birthdate = "1963/11/22"
|
41
|
+
expect(@instance.birthdate).to eql Date.new(1963, 11, 22)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should cast booleans correctly" do
|
45
|
+
@instance.rockstar = 1
|
46
|
+
expect(@instance.rockstar).to eql true
|
47
|
+
|
48
|
+
@instance.rockstar = "1"
|
49
|
+
expect(@instance.rockstar).to eql true
|
50
|
+
|
51
|
+
@instance.rockstar = "t"
|
52
|
+
expect(@instance.rockstar).to eql true
|
53
|
+
|
54
|
+
@instance.rockstar = "true"
|
55
|
+
expect(@instance.rockstar).to eql true
|
56
|
+
|
57
|
+
@instance.rockstar = 0
|
58
|
+
expect(@instance.rockstar).to eql false
|
59
|
+
|
60
|
+
@instance.rockstar = "0"
|
61
|
+
expect(@instance.rockstar).to eql false
|
62
|
+
|
63
|
+
@instance.rockstar = "f"
|
64
|
+
expect(@instance.rockstar).to eql false
|
65
|
+
|
66
|
+
@instance.rockstar = "false"
|
67
|
+
expect(@instance.rockstar).to eql false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should cast integer correctly" do
|
71
|
+
@instance.age = "23"
|
72
|
+
expect(@instance.age).to eql 23
|
73
|
+
|
74
|
+
@instance.age = "23 apples"
|
75
|
+
expect(@instance.age).to eql 23
|
76
|
+
|
77
|
+
@instance.age = "I have 23 apples"
|
78
|
+
expect(@instance.age).to eql 0
|
79
|
+
|
80
|
+
@instance.age = 42.0
|
81
|
+
expect(@instance.age).to eql 42
|
82
|
+
|
83
|
+
@instance.age = BigDecimal.new('42.67')
|
84
|
+
expect(@instance.age).to eql 42
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should cast strings correctly" do
|
88
|
+
@instance.username = 42
|
89
|
+
expect(@instance.username).to eql "42"
|
90
|
+
|
91
|
+
@instance.username = String
|
92
|
+
expect(@instance.username).to eql "String"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "Default values" do
|
97
|
+
before :each do
|
98
|
+
@klass = Class.new(VirtualAttributes::Base) do
|
99
|
+
string :fullname, default: "John Doe"
|
100
|
+
string :login, default: ->(e){ e.fullname.reverse }
|
101
|
+
date :birthdate, default: ->(){ raise ArgumentError }
|
102
|
+
date :birthdate_to_cast, default: "1963/11/22"
|
103
|
+
boolean :rockstar
|
104
|
+
integer :age
|
105
|
+
end
|
106
|
+
@instance = @klass.new
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should return default value when nil" do
|
110
|
+
expect(@instance.fullname).to eql 'John Doe'
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should ignore default value if not nil" do
|
114
|
+
@instance.fullname = 'Stephen King'
|
115
|
+
expect(@instance.fullname).to_not eql 'John Doe'
|
116
|
+
expect(@instance.fullname).to eql 'Stephen King'
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should ignore default value even if blank" do
|
120
|
+
@instance.fullname = ''
|
121
|
+
expect(@instance.fullname).to_not eql 'John Doe'
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should call default value proc" do
|
125
|
+
expect{@instance.birthdate}.to raise_error(ArgumentError)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should allow passing the model to default value procs" do
|
129
|
+
expect(@instance.login).to eql "eoD nhoJ"
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should cast default value" do
|
133
|
+
expect(@instance.birthdate_to_cast).to eql Date.new(1963, 11, 22)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "Validations" do
|
138
|
+
before :each do
|
139
|
+
@klass = ValidationTestClass = Class.new(VirtualAttributes::Base) do
|
140
|
+
string :fullname, default: ""
|
141
|
+
string :login, default: ->(e){ e.fullname.reverse }
|
142
|
+
date :birthdate, default: "1963/11/22"
|
143
|
+
boolean :rockstar, default: false
|
144
|
+
integer :age
|
145
|
+
|
146
|
+
validates_presence_of :fullname, :login, :age
|
147
|
+
end
|
148
|
+
@instance = @klass.new
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should validate correctly" do
|
152
|
+
expect(@instance.valid?).to be(false)
|
153
|
+
|
154
|
+
expect(@instance.errors[:fullname].length).to eql 1
|
155
|
+
expect(@instance.errors[:login].length).to eql 1
|
156
|
+
expect(@instance.errors[:age].length).to eql 1
|
157
|
+
expect(@instance.errors[:birthdate].length).to eql 0
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe VirtualAttributes::Serialization do
|
4
|
+
before :each do
|
5
|
+
@klass = ValidationTestSerializeClass = Class.new(ActiveRecord::Base) do
|
6
|
+
concerning :NoNeedDatabase do
|
7
|
+
attr_accessor :contact
|
8
|
+
|
9
|
+
def initialize(*)
|
10
|
+
end
|
11
|
+
|
12
|
+
def save(validate = true)
|
13
|
+
validate ? valid? : true
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def columns
|
18
|
+
@columns ||= [];
|
19
|
+
end
|
20
|
+
|
21
|
+
def column(name, sql_type = nil, default = nil, null = true)
|
22
|
+
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,
|
23
|
+
sql_type.to_s, null)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
serialize :contact do |t|
|
29
|
+
t.string :fullname, default: ""
|
30
|
+
t.string :login, default: ->(e){ e.fullname.reverse }
|
31
|
+
t.date :birthdate, default: "1963/11/22"
|
32
|
+
t.boolean :rockstar, default: false
|
33
|
+
t.integer :age
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@instance = @klass.new
|
38
|
+
end
|
39
|
+
|
40
|
+
it "create a namespaced class of the right type" do
|
41
|
+
expect(@klass).to be_const_defined(:'ContactVirtualAttributes')
|
42
|
+
expect(@klass.const_get(:'ContactVirtualAttributes').superclass).to eql(VirtualAttributes::Base)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should produce instances that return the right type" do
|
46
|
+
expect(@instance.contact).to be_a(VirtualAttributes::Base)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should accept open structs and hashes" do
|
50
|
+
expect{ @instance.contact = OpenStruct.new(fullname: 'John Doe') }.to_not raise_error
|
51
|
+
expect(@instance.contact.fullname).to eql 'John Doe'
|
52
|
+
|
53
|
+
expect{ @instance.contact = {login: 'John Doe'} }.to_not raise_error
|
54
|
+
expect(@instance.contact.login).to eql 'John Doe'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should refuses other types" do
|
58
|
+
expect{ @instance.contact = 42 }.to raise_error(/is not convertible/)
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'virtual-attributes'
|
5
|
+
s.version = '0.1.1'
|
6
|
+
s.date = '2015-03-19'
|
7
|
+
s.summary = "Enhance ActiveRecord's Serialize with types attributes"
|
8
|
+
s.description = "This gem allow you to add whenever columns you want to your model through one single serialized attribute"
|
9
|
+
s.authors = ["ihcene"]
|
10
|
+
s.email = 'ihcene@aritylabs.com'
|
11
|
+
s.files = `git ls-files`.split($/)
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.required_ruby_version = '>= 1.9.3'
|
14
|
+
s.homepage = 'https://github.com/ihcene/virtual-attributes'
|
15
|
+
s.license = 'MIT'
|
16
|
+
s.add_runtime_dependency 'activerecord', '>= 3.0', '< 5.0'
|
17
|
+
s.add_development_dependency 'rspec', '~> 3.2', '>= 3.2.0'
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: virtual-attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ihcene
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 3.2.0
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '3.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 3.2.0
|
53
|
+
description: This gem allow you to add whenever columns you want to your model through
|
54
|
+
one single serialized attribute
|
55
|
+
email: ihcene@aritylabs.com
|
56
|
+
executables: []
|
57
|
+
extensions: []
|
58
|
+
extra_rdoc_files: []
|
59
|
+
files:
|
60
|
+
- ".rspec"
|
61
|
+
- LICENSE
|
62
|
+
- lib/virtual-attributes.rb
|
63
|
+
- lib/virtual-attributes/base.rb
|
64
|
+
- lib/virtual-attributes/base/attributes.rb
|
65
|
+
- lib/virtual-attributes/base/casts.rb
|
66
|
+
- lib/virtual-attributes/base/conversions.rb
|
67
|
+
- lib/virtual-attributes/base/defaults.rb
|
68
|
+
- lib/virtual-attributes/base/validations.rb
|
69
|
+
- lib/virtual-attributes/serialization.rb
|
70
|
+
- spec/base_spec.rb
|
71
|
+
- spec/serialization_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
- virtual-attributes.gemspec
|
74
|
+
homepage: https://github.com/ihcene/virtual-attributes
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.9.3
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.2.2
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Enhance ActiveRecord's Serialize with types attributes
|
98
|
+
test_files: []
|