clean_model 0.0.5 → 0.0.6
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.
- data/.gitignore +5 -5
- data/Gemfile +4 -4
- data/README.md +211 -211
- data/Rakefile +1 -1
- data/clean_model.gemspec +24 -25
- data/lib/clean_model/attribute.rb +55 -55
- data/lib/clean_model/base.rb +62 -62
- data/lib/clean_model/exceptions.rb +17 -29
- data/lib/clean_model/persistent.rb +75 -75
- data/lib/clean_model/remote.rb +75 -96
- data/lib/clean_model/version.rb +3 -3
- data/lib/clean_model.rb +11 -11
- data/spec/base_model_spec.rb +177 -177
- data/spec/persistent_model_spec.rb +111 -111
- data/spec/remote_models_spec.rb +147 -147
- data/spec/spec_helper.rb +7 -7
- data/spec/support/models/base_models.rb +36 -36
- data/spec/support/models/persistent_models.rb +9 -9
- data/spec/support/models/remote_models.rb +12 -12
- metadata +29 -20
data/lib/clean_model/base.rb
CHANGED
@@ -1,63 +1,63 @@
|
|
1
|
-
module CleanModel
|
2
|
-
module Base
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
base.send :extend, ClassMethods
|
6
|
-
base.send :include, InstanceMethods
|
7
|
-
base.send :extend, ActiveModel::Translation
|
8
|
-
base.send :include, ActiveModel::Validations
|
9
|
-
end
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
|
13
|
-
def attribute(name, options={})
|
14
|
-
attr = Attribute.new(name, options)
|
15
|
-
attributes << attr
|
16
|
-
|
17
|
-
define_method name do
|
18
|
-
instance_variable_get "@#{name}"
|
19
|
-
end
|
20
|
-
|
21
|
-
define_method "#{name}=" do |value|
|
22
|
-
value = attr.transform(value)
|
23
|
-
attr.validate!(value)
|
24
|
-
instance_variable_set "@#{name}", value
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def attributes
|
29
|
-
@attributes ||= []
|
30
|
-
end
|
31
|
-
|
32
|
-
def attribute_names
|
33
|
-
attributes.map(&:name)
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
module InstanceMethods
|
39
|
-
|
40
|
-
def initialize(attributes={})
|
41
|
-
self.class.attributes.each { |a| a.assign_default(self) }
|
42
|
-
if block_given?
|
43
|
-
yield(self)
|
44
|
-
else
|
45
|
-
assign_attributes attributes
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def assign_attributes(attributes)
|
50
|
-
return nil unless attributes
|
51
|
-
attributes.each do |name, value|
|
52
|
-
send("#{name}=", value) if respond_to?("#{name}=")
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def attributes
|
57
|
-
Hash[self.class.attribute_names.map { |a| [a, send(a)] }]
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
1
|
+
module CleanModel
|
2
|
+
module Base
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
base.send :include, InstanceMethods
|
7
|
+
base.send :extend, ActiveModel::Translation
|
8
|
+
base.send :include, ActiveModel::Validations
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
def attribute(name, options={})
|
14
|
+
attr = Attribute.new(name, options)
|
15
|
+
attributes << attr
|
16
|
+
|
17
|
+
define_method name do
|
18
|
+
instance_variable_get "@#{name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method "#{name}=" do |value|
|
22
|
+
value = attr.transform(value)
|
23
|
+
attr.validate!(value)
|
24
|
+
instance_variable_set "@#{name}", value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def attributes
|
29
|
+
@attributes ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def attribute_names
|
33
|
+
attributes.map(&:name)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
module InstanceMethods
|
39
|
+
|
40
|
+
def initialize(attributes={})
|
41
|
+
self.class.attributes.each { |a| a.assign_default(self) }
|
42
|
+
if block_given?
|
43
|
+
yield(self)
|
44
|
+
else
|
45
|
+
assign_attributes attributes
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def assign_attributes(attributes)
|
50
|
+
return nil unless attributes
|
51
|
+
attributes.each do |name, value|
|
52
|
+
send("#{name}=", value) if respond_to?("#{name}=")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def attributes
|
57
|
+
Hash[self.class.attribute_names.map { |a| [a, send(a)] }]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
63
|
end
|
@@ -1,30 +1,18 @@
|
|
1
|
-
module CleanModel
|
2
|
-
|
3
|
-
class Error < StandardError
|
4
|
-
end
|
5
|
-
|
6
|
-
class InvalidTypeAssignment < Error
|
7
|
-
def initialize(attribute, value)
|
8
|
-
super "#{value} is not valid for #{attribute}"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class UndefinedPersistenceMethod < Error
|
13
|
-
def initialize(klass, method)
|
14
|
-
super "#{klass} must define method [#{method}]"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class InvalidResponse < Error
|
19
|
-
def initialize(response)
|
20
|
-
super response.content_type == 'application/json' ? response.body : "#{response.code} - Unexpected error"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class ConnectionFail < Error
|
25
|
-
def initialize(exception)
|
26
|
-
super exception.message
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
1
|
+
module CleanModel
|
2
|
+
|
3
|
+
class Error < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class InvalidTypeAssignment < Error
|
7
|
+
def initialize(attribute, value)
|
8
|
+
super "#{value} is not valid for #{attribute}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class UndefinedPersistenceMethod < Error
|
13
|
+
def initialize(klass, method)
|
14
|
+
super "#{klass} must define method [#{method}]"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
30
18
|
end
|
@@ -1,76 +1,76 @@
|
|
1
|
-
module CleanModel
|
2
|
-
module Persistent
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
base.send :include, Base
|
6
|
-
base.send :extend, ClassMethods
|
7
|
-
base.send :include, InstanceMethods
|
8
|
-
base.send :include, ActiveModel::Conversion
|
9
|
-
|
10
|
-
base.attribute :id
|
11
|
-
end
|
12
|
-
|
13
|
-
module ClassMethods
|
14
|
-
|
15
|
-
def create(attributes={})
|
16
|
-
begin
|
17
|
-
create! attributes
|
18
|
-
rescue
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def create!(attributes={})
|
24
|
-
model = new attributes
|
25
|
-
model.save!
|
26
|
-
model
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
module InstanceMethods
|
32
|
-
|
33
|
-
def new_record?
|
34
|
-
id.nil?
|
35
|
-
end
|
36
|
-
|
37
|
-
def persisted?
|
38
|
-
!new_record?
|
39
|
-
end
|
40
|
-
|
41
|
-
def save!
|
42
|
-
raise errors.full_messages.join("\n") unless save
|
43
|
-
end
|
44
|
-
|
45
|
-
def save
|
46
|
-
return false unless valid?
|
47
|
-
new_record? ? create : update
|
48
|
-
end
|
49
|
-
|
50
|
-
def update_attributes(attributes)
|
51
|
-
assign_attributes attributes
|
52
|
-
save
|
53
|
-
end
|
54
|
-
|
55
|
-
def destroy
|
56
|
-
delete
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def create
|
62
|
-
raise UndefinedPersistenceMethod.new(self.class, :create)
|
63
|
-
end
|
64
|
-
|
65
|
-
def update
|
66
|
-
raise UndefinedPersistenceMethod.new(self.class, :update)
|
67
|
-
end
|
68
|
-
|
69
|
-
def delete
|
70
|
-
raise UndefinedPersistenceMethod.new(self.class, :delete)
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
1
|
+
module CleanModel
|
2
|
+
module Persistent
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :include, Base
|
6
|
+
base.send :extend, ClassMethods
|
7
|
+
base.send :include, InstanceMethods
|
8
|
+
base.send :include, ActiveModel::Conversion
|
9
|
+
|
10
|
+
base.attribute :id
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
def create(attributes={})
|
16
|
+
begin
|
17
|
+
create! attributes
|
18
|
+
rescue
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create!(attributes={})
|
24
|
+
model = new attributes
|
25
|
+
model.save!
|
26
|
+
model
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
module InstanceMethods
|
32
|
+
|
33
|
+
def new_record?
|
34
|
+
id.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def persisted?
|
38
|
+
!new_record?
|
39
|
+
end
|
40
|
+
|
41
|
+
def save!
|
42
|
+
raise errors.full_messages.join("\n") unless save
|
43
|
+
end
|
44
|
+
|
45
|
+
def save
|
46
|
+
return false unless valid?
|
47
|
+
new_record? ? create : update
|
48
|
+
end
|
49
|
+
|
50
|
+
def update_attributes(attributes)
|
51
|
+
assign_attributes attributes
|
52
|
+
save
|
53
|
+
end
|
54
|
+
|
55
|
+
def destroy
|
56
|
+
delete
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def create
|
62
|
+
raise UndefinedPersistenceMethod.new(self.class, :create)
|
63
|
+
end
|
64
|
+
|
65
|
+
def update
|
66
|
+
raise UndefinedPersistenceMethod.new(self.class, :update)
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete
|
70
|
+
raise UndefinedPersistenceMethod.new(self.class, :delete)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
76
|
end
|
data/lib/clean_model/remote.rb
CHANGED
@@ -1,97 +1,76 @@
|
|
1
|
-
module CleanModel
|
2
|
-
module Remote
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
base.send :include, Persistent
|
6
|
-
base.send :extend, ClassMethods
|
7
|
-
base.send :include, InstanceMethods
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
|
12
|
-
def connection(connection=nil)
|
13
|
-
connection ? @connection = connection : @connection
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def
|
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
|
-
def
|
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
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def save_success(response)
|
81
|
-
assign_attributes JSON.parse(response.body) if response.body
|
82
|
-
end
|
83
|
-
|
84
|
-
def save_fail(response)
|
85
|
-
if response.code.to_i == 422 #:unprocessable_entity
|
86
|
-
JSON.parse(response.body).each do |attribute, messages|
|
87
|
-
messages.each { |m| errors[attribute.to_sym] << m }
|
88
|
-
end
|
89
|
-
else
|
90
|
-
errors[:base] = response.content_type == 'application/json' ? response.body : "#{response.code} - Unexpected error"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
1
|
+
module CleanModel
|
2
|
+
module Remote
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :include, Persistent
|
6
|
+
base.send :extend, ClassMethods
|
7
|
+
base.send :include, InstanceMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def connection(connection=nil)
|
13
|
+
connection ? @connection = WebClient::Connection.new(connection) : @connection
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
|
20
|
+
def save
|
21
|
+
return false unless valid?
|
22
|
+
begin
|
23
|
+
response = new_record? ? create : update
|
24
|
+
if response.success?
|
25
|
+
save_success(response)
|
26
|
+
else
|
27
|
+
save_fail(response)
|
28
|
+
end
|
29
|
+
rescue WebClient::Error => ex
|
30
|
+
errors[:base] = ex.message
|
31
|
+
end
|
32
|
+
errors.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
return true if new_record?
|
37
|
+
begin
|
38
|
+
response = delete
|
39
|
+
unless response.success?
|
40
|
+
errors[:base] = response.content_type == 'application/json' ? response.body : "#{response.code} - Unexpected error"
|
41
|
+
end
|
42
|
+
rescue WebClient::Error => ex
|
43
|
+
errors[:base] = ex.message
|
44
|
+
end
|
45
|
+
errors.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def connection
|
51
|
+
self.class.connection
|
52
|
+
end
|
53
|
+
|
54
|
+
def wrapped_attributes(options={})
|
55
|
+
exceptions = options[:except] ? [options[:except]].flatten.map(&:to_sym) : []
|
56
|
+
attributes.reject { |k, v| v.nil? || exceptions.include?(k) }.inject({}) { |h, (k, v)| h["#{options[:wrapper] || self.class.to_s.demodulize.underscore}[#{k}]"] = v; h }
|
57
|
+
end
|
58
|
+
|
59
|
+
def save_success(response)
|
60
|
+
assign_attributes JSON.parse(response.body) if response.body
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_fail(response)
|
64
|
+
if response.code.to_i == 422 #:unprocessable_entity
|
65
|
+
JSON.parse(response.body).each do |attribute, messages|
|
66
|
+
messages.each { |m| errors[attribute.to_sym] << m }
|
67
|
+
end
|
68
|
+
else
|
69
|
+
errors[:base] = response.content_type == 'application/json' ? response.body : "#{response.code} - Unexpected error"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
97
76
|
end
|
data/lib/clean_model/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module CleanModel
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
1
|
+
module CleanModel
|
2
|
+
VERSION = '0.0.6'
|
3
|
+
end
|
data/lib/clean_model.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'active_model'
|
2
|
-
require 'active_support/all'
|
3
|
-
require 'web_client'
|
4
|
-
require 'json'
|
5
|
-
|
6
|
-
require 'clean_model/version'
|
7
|
-
require 'clean_model/attribute'
|
8
|
-
require 'clean_model/exceptions'
|
9
|
-
require 'clean_model/base'
|
10
|
-
require 'clean_model/persistent'
|
11
|
-
require 'clean_model/remote'
|
1
|
+
require 'active_model'
|
2
|
+
require 'active_support/all'
|
3
|
+
require 'web_client'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require 'clean_model/version'
|
7
|
+
require 'clean_model/attribute'
|
8
|
+
require 'clean_model/exceptions'
|
9
|
+
require 'clean_model/base'
|
10
|
+
require 'clean_model/persistent'
|
11
|
+
require 'clean_model/remote'
|