active_repository 0.0.1 → 0.0.3
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 +1 -0
- data/.travis.yml +10 -0
- data/README.md +23 -3
- data/Rakefile +10 -0
- data/active_repository.gemspec +7 -3
- data/lib/active_repository/associations.rb +2 -7
- data/lib/active_repository/base.rb +40 -150
- data/lib/active_repository/finders.rb +101 -0
- data/lib/active_repository/sql_query_executor.rb +26 -14
- data/lib/active_repository/version.rb +1 -1
- data/lib/active_repository/write_support.rb +31 -14
- data/lib/active_repository/writers.rb +67 -0
- data/spec/active_repository/associations_spec.rb +348 -0
- data/spec/active_repository/base_spec.rb +68 -2
- data/spec/active_repository/sql_query_executor_spec.rb +0 -1
- data/spec/support/shared_examples.rb +78 -19
- data/support/mongoid.yml +6 -0
- metadata +30 -8
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,14 +1,34 @@
|
|
1
1
|
# ActiveRepository
|
2
2
|
|
3
|
-
|
3
|
+
[](http://travis-ci.org/efreesen/active_repository)[](https://gemnasium.com/efreesen/active_repository) [](https://codeclimate.com/github/efreesen/active_repository)
|
4
4
|
|
5
|
-
|
5
|
+
ActiveRepository was designed so you can build your Business Models without depending on any ORM. It by default saves your data in memory using ActiveHash (https://github.com/zilkey/active_hash). Then when you decide which ORM you want to use you only have to connect ActiveRepository with it.
|
6
|
+
|
7
|
+
Currently it only works with ActiveRecord and/or Mongoid.
|
8
|
+
|
9
|
+
It also has the advantage of letting you test directly in memory, with no need to save data on disk, which gives a great boost to your test suite speed.
|
10
|
+
|
11
|
+
Here are some data for comparison:
|
12
|
+
|
13
|
+
* **ActiveRepository:**
|
14
|
+
Finished in **0.63357** seconds;
|
15
|
+
78 examples, 0 failures
|
16
|
+
|
17
|
+
* **ActiveRecord:**
|
18
|
+
Finished in **3.78** seconds;
|
19
|
+
78 examples, 0 failures
|
20
|
+
|
21
|
+
* **Mongoid:**
|
22
|
+
Finished in **5.25** seconds;
|
23
|
+
78 examples, 0 failures
|
24
|
+
|
25
|
+
With ActiveRepository you can make associations with ActiveRecord, Mongoid and ActiveRepository seamlessly.
|
6
26
|
|
7
27
|
## Requirements
|
8
28
|
|
9
29
|
### Ruby
|
10
30
|
|
11
|
-
ActiveRepository requires Ruby version **>= 1.9.
|
31
|
+
ActiveRepository requires Ruby version **>= 1.9.3**.
|
12
32
|
|
13
33
|
## Installation
|
14
34
|
|
data/Rakefile
CHANGED
@@ -1,2 +1,12 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
desc 'Default: run rspec tests.'
|
5
|
+
task :default => [:travis]
|
6
|
+
|
7
|
+
task :travis do
|
8
|
+
cmd = "rspec spec"
|
9
|
+
puts "Starting to run `#{cmd}`..."
|
10
|
+
system("export DISPLAY=:99.0 && bundle exec rspec spec -c")
|
11
|
+
raise "#{cmd} failed!" unless $?.exitstatus == 0
|
12
|
+
end
|
data/active_repository.gemspec
CHANGED
@@ -16,8 +16,12 @@ Gem::Specification.new do |gem|
|
|
16
16
|
|
17
17
|
gem.add_runtime_dependency(%q<active_hash>, [">= 0.9.12"])
|
18
18
|
gem.add_runtime_dependency(%q<activemodel>, [">= 3.2.6"])
|
19
|
-
gem.add_development_dependency(%q<rspec>, ["
|
20
|
-
gem.add_development_dependency(%q<sqlite3>)
|
19
|
+
gem.add_development_dependency(%q<rspec>, [">= 2.2.0"])
|
21
20
|
gem.add_development_dependency(%q<activerecord>)
|
22
|
-
gem.add_development_dependency(%q<mongoid
|
21
|
+
gem.add_development_dependency(%q<mongoid>, ["= 3.0.11"])
|
22
|
+
gem.add_development_dependency('rake')
|
23
|
+
gem.add_development_dependency(%q<sqlite3>) unless RUBY_PLATFORM == 'java'
|
24
|
+
gem.add_development_dependency(%q<jdbc-sqlite3>) if RUBY_PLATFORM == 'java'
|
25
|
+
gem.add_development_dependency(%q<jruby-openssl>) if RUBY_PLATFORM == 'java'
|
26
|
+
gem.add_development_dependency(%q<activerecord-jdbcsqlite3-adapter>) if RUBY_PLATFORM == 'java'
|
23
27
|
end
|
@@ -3,7 +3,7 @@ module ActiveRepository
|
|
3
3
|
|
4
4
|
module ActiveRecordExtensions
|
5
5
|
|
6
|
-
def
|
6
|
+
def belongs_to_active_repository(association_id, options = {})
|
7
7
|
options = {
|
8
8
|
:class_name => association_id.to_s.classify,
|
9
9
|
:foreign_key => association_id.to_s.foreign_key
|
@@ -33,7 +33,6 @@ module ActiveRepository
|
|
33
33
|
|
34
34
|
module Methods
|
35
35
|
def has_many(association_id, options = {})
|
36
|
-
|
37
36
|
define_method(association_id) do
|
38
37
|
options = {
|
39
38
|
:class_name => association_id.to_s.classify,
|
@@ -48,8 +47,6 @@ module ActiveRepository
|
|
48
47
|
else
|
49
48
|
objects = klass.send("find_all_by_#{options[:foreign_key]}", id)
|
50
49
|
end
|
51
|
-
|
52
|
-
objects.map{ |o| self.serialize!(o.attributes) }
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
@@ -79,13 +76,11 @@ module ActiveRepository
|
|
79
76
|
field options[:foreign_key].to_sym
|
80
77
|
|
81
78
|
define_method(association_id) do
|
82
|
-
klass =
|
79
|
+
klass = options[:class_name].constantize
|
83
80
|
id = send(options[:foreign_key])
|
84
81
|
|
85
82
|
if id.present?
|
86
83
|
object = klass.find_by_id(id)
|
87
|
-
|
88
|
-
object.nil? || object.class == self.class ? object : self.class.serialize!(object.attributes)
|
89
84
|
else
|
90
85
|
nil
|
91
86
|
end
|
@@ -2,95 +2,26 @@ require 'active_repository/associations'
|
|
2
2
|
require 'active_repository/uniqueness'
|
3
3
|
require 'active_repository/write_support'
|
4
4
|
require 'active_repository/sql_query_executor'
|
5
|
+
require 'active_repository/finders'
|
6
|
+
require 'active_repository/writers'
|
5
7
|
|
6
8
|
module ActiveRepository
|
7
9
|
|
8
10
|
class Base < ActiveHash::Base
|
9
11
|
extend ActiveModel::Callbacks
|
12
|
+
extend ActiveRepository::Finders
|
13
|
+
extend ActiveRepository::Writers
|
10
14
|
include ActiveModel::Validations
|
11
15
|
include ActiveModel::Validations::Callbacks
|
12
16
|
include ActiveRepository::Associations
|
17
|
+
include ActiveRepository::Writers::InstanceMethods
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
class_attribute :model_class, :save_in_memory
|
19
|
+
class_attribute :model_class, :save_in_memory, :instance_writer => false
|
17
20
|
|
18
21
|
before_validation :set_timestamps
|
19
22
|
|
20
23
|
fields :created_at, :updated_at
|
21
24
|
|
22
|
-
def self.define_custom_find_by_field(field_name)
|
23
|
-
method_name = :"find_by_#{field_name}"
|
24
|
-
unless has_singleton_method?(method_name)
|
25
|
-
the_meta_class.instance_eval do
|
26
|
-
define_method(method_name) do |*args|
|
27
|
-
object = get_model_class.send(method_name)
|
28
|
-
object.nil? ? nil : serialize!(object.attributes)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.define_custom_find_by_field(field_name)
|
35
|
-
method_name = :"find_by_#{field_name}"
|
36
|
-
the_meta_class.instance_eval do
|
37
|
-
define_method(method_name) do |*args|
|
38
|
-
object = nil
|
39
|
-
|
40
|
-
if self == get_model_class
|
41
|
-
object = self.where(field_name.to_sym => args.first).first
|
42
|
-
else
|
43
|
-
object = get_model_class.send(method_name, args)
|
44
|
-
end
|
45
|
-
|
46
|
-
object.nil? ? nil : serialize!(object.attributes)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.define_custom_find_all_by_field(field_name)
|
52
|
-
method_name = :"find_all_by_#{field_name}"
|
53
|
-
the_meta_class.instance_eval do
|
54
|
-
define_method(method_name) do |*args|
|
55
|
-
objects = []
|
56
|
-
|
57
|
-
if self == get_model_class
|
58
|
-
objects = self.where(field_name.to_sym => args.first)
|
59
|
-
else
|
60
|
-
objects = get_model_class.send(method_name, args)
|
61
|
-
end
|
62
|
-
|
63
|
-
objects.empty? ? [] : objects.map{ |object| serialize!(object.attributes) }
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.find(id)
|
69
|
-
begin
|
70
|
-
if self == get_model_class
|
71
|
-
super(id)
|
72
|
-
else
|
73
|
-
object = get_model_class.find(id)
|
74
|
-
|
75
|
-
if object.is_a?(Array)
|
76
|
-
object.map { |o| serialize!(o.attributes) }
|
77
|
-
else
|
78
|
-
serialize!(object.attributes)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
rescue Exception => e
|
82
|
-
message = ""
|
83
|
-
|
84
|
-
if id.is_a?(Array)
|
85
|
-
message = "Couldn't find all #{self} objects with IDs (#{id.join(', ')})"
|
86
|
-
else
|
87
|
-
message = "Couldn't find #{self} with ID=#{id}"
|
88
|
-
end
|
89
|
-
|
90
|
-
raise ActiveHash::RecordNotFound.new(message)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
25
|
def reload
|
95
26
|
serialize! self.class.get_model_class.find(self.id).attributes
|
96
27
|
end
|
@@ -99,46 +30,12 @@ module ActiveRepository
|
|
99
30
|
if self == get_model_class
|
100
31
|
!find_by_id(id).nil?
|
101
32
|
else
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
if self == get_model_class
|
108
|
-
super(id)
|
109
|
-
else
|
110
|
-
get_model_class.find_by_id(id)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.find_or_create(attributes)
|
115
|
-
object = get_model_class.where(attributes).first
|
116
|
-
|
117
|
-
object = model_class.create(attributes) if object.nil?
|
118
|
-
|
119
|
-
serialize!(object.attributes)
|
120
|
-
end
|
121
|
-
|
122
|
-
def self.create(attributes={})
|
123
|
-
object = get_model_class.new(attributes)
|
124
|
-
|
125
|
-
object.id = nil if get_model_class.exists?(object.id)
|
126
|
-
|
127
|
-
object.save
|
128
|
-
|
129
|
-
serialize!(object.attributes) unless object.class.name == self
|
130
|
-
end
|
131
|
-
|
132
|
-
def update_attributes(attributes)
|
133
|
-
object = self.class.get_model_class.find(self.id)
|
134
|
-
|
135
|
-
attributes.each do |k,v|
|
136
|
-
object.send("#{k.to_s}=", v) unless k == :id
|
33
|
+
if mongoid?
|
34
|
+
find_by_id(id).present?
|
35
|
+
else
|
36
|
+
get_model_class.exists?(id)
|
37
|
+
end
|
137
38
|
end
|
138
|
-
|
139
|
-
object.save
|
140
|
-
|
141
|
-
self.attributes = object.attributes
|
142
39
|
end
|
143
40
|
|
144
41
|
def self.all
|
@@ -184,32 +81,17 @@ module ActiveRepository
|
|
184
81
|
end
|
185
82
|
end
|
186
83
|
|
187
|
-
def self.first
|
188
|
-
get("first")
|
189
|
-
end
|
190
|
-
|
191
|
-
def self.last
|
192
|
-
get("last")
|
193
|
-
end
|
194
|
-
|
195
|
-
def self.get(position)
|
196
|
-
if self == get_model_class
|
197
|
-
id = get_model_class.all.map(&:id).sort.send(position)
|
198
|
-
|
199
|
-
self.find id
|
200
|
-
else
|
201
|
-
serialize! get_model_class.send(position).attributes
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
84
|
def convert(attribute="id")
|
206
|
-
|
85
|
+
klass = self.class.get_model_class
|
86
|
+
object = klass.where(attribute.to_sym => self.send(attribute)).first
|
207
87
|
|
208
|
-
object
|
88
|
+
object ||= self.class.get_model_class.new
|
209
89
|
|
210
|
-
self.attributes
|
211
|
-
|
212
|
-
|
90
|
+
attributes = self.attributes
|
91
|
+
|
92
|
+
attributes.delete(:id)
|
93
|
+
|
94
|
+
object.attributes = attributes
|
213
95
|
|
214
96
|
object.save
|
215
97
|
|
@@ -218,26 +100,21 @@ module ActiveRepository
|
|
218
100
|
object
|
219
101
|
end
|
220
102
|
|
221
|
-
def attributes=(new_attributes)
|
222
|
-
new_attributes.each do |k,v|
|
223
|
-
self.send("#{k.to_s}=", v)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
103
|
def serialize!(attributes)
|
228
104
|
unless attributes.nil?
|
229
|
-
attributes
|
230
|
-
self.send("#{k.to_s}=", v)
|
231
|
-
end
|
105
|
+
self.attributes = attributes
|
232
106
|
end
|
233
107
|
|
234
108
|
self
|
235
109
|
end
|
236
110
|
|
237
|
-
def self.serialize!(
|
238
|
-
|
239
|
-
|
240
|
-
|
111
|
+
def self.serialize!(other)
|
112
|
+
case other.class.to_s
|
113
|
+
when "Hash" then self.new.serialize!(other)
|
114
|
+
when "Array" then other.map { |o| serialize!(o.attributes) }
|
115
|
+
when "Moped::BSON::Document" then self.new.serialize!(other)
|
116
|
+
else self.new.serialize!(other.attributes)
|
117
|
+
end
|
241
118
|
end
|
242
119
|
|
243
120
|
def self.serialized_attributes
|
@@ -249,9 +126,14 @@ module ActiveRepository
|
|
249
126
|
end
|
250
127
|
|
251
128
|
def self.get_model_class
|
129
|
+
return self if self.save_in_memory.nil?
|
252
130
|
save_in_memory? ? self : self.model_class
|
253
131
|
end
|
254
132
|
|
133
|
+
def save_in_memory?
|
134
|
+
self.save_in_memory.nil? ? true : save_in_memory
|
135
|
+
end
|
136
|
+
|
255
137
|
protected
|
256
138
|
def model_class
|
257
139
|
self.model_class
|
@@ -262,5 +144,13 @@ module ActiveRepository
|
|
262
144
|
self.created_at = DateTime.now.utc if self.new_record?
|
263
145
|
self.updated_at = DateTime.now.utc
|
264
146
|
end
|
147
|
+
|
148
|
+
def self.mongoid?
|
149
|
+
get_model_class.included_modules.include?(Mongoid::Document)
|
150
|
+
end
|
151
|
+
|
152
|
+
def mongoid?
|
153
|
+
self.class.mongoid?
|
154
|
+
end
|
265
155
|
end
|
266
156
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module ActiveRepository
|
2
|
+
module Finders
|
3
|
+
def define_custom_find_by_field(field_name)
|
4
|
+
method_name = :"find_all_by_#{field_name}"
|
5
|
+
the_meta_class.instance_eval do
|
6
|
+
define_method(method_name) do |*args|
|
7
|
+
object = nil
|
8
|
+
|
9
|
+
object = self.find_by_field(field_name.to_sym, args)
|
10
|
+
|
11
|
+
object.nil? ? nil : serialize!(object.attributes)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def define_custom_find_all_by_field(field_name)
|
17
|
+
method_name = :"find_all_by_#{field_name}"
|
18
|
+
the_meta_class.instance_eval do
|
19
|
+
define_method(method_name) do |*args|
|
20
|
+
objects = []
|
21
|
+
|
22
|
+
objects = self.find_all_by_field(field_name.to_sym, args)
|
23
|
+
|
24
|
+
objects.empty? ? [] : objects.map{ |object| serialize!(object.attributes) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_by_field(field_name, args)
|
30
|
+
self.find_all_by_field(field_name, args).first
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_all_by_field(field_name, args)
|
34
|
+
objects = []
|
35
|
+
|
36
|
+
if self == get_model_class
|
37
|
+
objects = self.where(field_name.to_sym => args.first)
|
38
|
+
else
|
39
|
+
if mongoid?
|
40
|
+
objects = get_model_class.where(field_name.to_sym => args.first)
|
41
|
+
else
|
42
|
+
method_name = :"find_all_by_#{field_name}"
|
43
|
+
objects = get_model_class.send(method_name, args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
objects
|
48
|
+
end
|
49
|
+
|
50
|
+
def find(id)
|
51
|
+
begin
|
52
|
+
if self == get_model_class
|
53
|
+
super(id)
|
54
|
+
else
|
55
|
+
object = (id == :all) ? all : get_model_class.find(id)
|
56
|
+
|
57
|
+
serialize!(object)
|
58
|
+
end
|
59
|
+
rescue Exception => e
|
60
|
+
message = "Couldn't find #{self} with ID=#{id}"
|
61
|
+
message = "Couldn't find all #{self} objects with IDs (#{id.join(', ')})" if id.is_a?(Array)
|
62
|
+
|
63
|
+
raise ActiveHash::RecordNotFound.new(message)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_by_id(id)
|
68
|
+
if self == get_model_class
|
69
|
+
super(id)
|
70
|
+
else
|
71
|
+
object = nil
|
72
|
+
|
73
|
+
if mongoid?
|
74
|
+
object = get_model_class.where(:id => id).entries.first
|
75
|
+
else
|
76
|
+
object = get_model_class.find_by_id(id)
|
77
|
+
end
|
78
|
+
|
79
|
+
object.nil? ? nil : serialize!(object.attributes)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def first
|
84
|
+
get("first")
|
85
|
+
end
|
86
|
+
|
87
|
+
def last
|
88
|
+
get("last")
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def get(position)
|
93
|
+
if self == get_model_class
|
94
|
+
all.sort_by!{ |o| o.id }.send(position)
|
95
|
+
else
|
96
|
+
object = get_model_class.send(position)
|
97
|
+
serialize! object.attributes
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -75,23 +75,35 @@ module ActiveHash
|
|
75
75
|
def execute_sub_query(klass, sub_query)
|
76
76
|
case @operator
|
77
77
|
when "between"
|
78
|
-
klass
|
79
|
-
field, first_attr, second_attr = convert_attrs(o.send(sub_query.first), sub_query[2], sub_query[4])
|
80
|
-
|
81
|
-
(field >= first_attr && field <= second_attr)
|
82
|
-
end
|
78
|
+
execute_between(klass, sub_query)
|
83
79
|
when "is"
|
84
|
-
klass
|
85
|
-
field = o.send(sub_query.first).blank?
|
86
|
-
|
87
|
-
sub_query.size == 3 ? field : !field
|
88
|
-
end
|
80
|
+
execute_is(klass, sub_query)
|
89
81
|
else
|
90
|
-
klass
|
91
|
-
|
82
|
+
execute_operator(klass, sub_query)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def execute_between(klass, sub_query)
|
87
|
+
klass.all.select do |o|
|
88
|
+
field, first_attr, second_attr = convert_attrs(o.send(sub_query.first), sub_query[2], sub_query[4])
|
89
|
+
|
90
|
+
(field >= first_attr && field <= second_attr)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def execute_is(klass, sub_query)
|
95
|
+
klass.all.select do |o|
|
96
|
+
field = o.send(sub_query.first).blank?
|
97
|
+
|
98
|
+
sub_query.size == 3 ? field : !field
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def execute_operator(klass, sub_query)
|
103
|
+
klass.all.select do |o|
|
104
|
+
field, attribute = convert_attrs(o.send(sub_query.first), sub_query[2])
|
92
105
|
|
93
|
-
|
94
|
-
end
|
106
|
+
field.blank? ? false : field.send(@operator, attribute)
|
95
107
|
end
|
96
108
|
end
|
97
109
|
|
@@ -18,22 +18,16 @@ end
|
|
18
18
|
module ActiveHash
|
19
19
|
class Base
|
20
20
|
def self.insert(record)
|
21
|
-
|
22
|
-
|
21
|
+
record_id = record.id.to_s
|
22
|
+
record_hash = record.hash
|
23
|
+
|
24
|
+
if self.all.map(&:hash).include?(record_hash)
|
25
|
+
record_index.delete(record_id)
|
23
26
|
self.all.delete(record)
|
24
27
|
end
|
25
28
|
|
26
|
-
if record_index[
|
27
|
-
|
28
|
-
record.attributes[:id] ||= next_id
|
29
|
-
|
30
|
-
validate_unique_id(record) if dirty
|
31
|
-
mark_dirty
|
32
|
-
|
33
|
-
if record.valid?
|
34
|
-
add_to_record_index({ record.id.to_s => @records.length })
|
35
|
-
@records << record
|
36
|
-
end
|
29
|
+
if record_index[record_id].nil? || !self.all.map(&:hash).include?(record_hash)
|
30
|
+
insert_record(record)
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
@@ -51,6 +45,11 @@ module ActiveHash
|
|
51
45
|
raise IdError.new("Duplicate Id found for record #{record.attributes}") if record_index.has_key?(record.id.to_s)
|
52
46
|
end
|
53
47
|
|
48
|
+
def update_attribute(key, value)
|
49
|
+
self.send("#{key}=", value)
|
50
|
+
self.save(:validate => false)
|
51
|
+
end
|
52
|
+
|
54
53
|
def readonly?
|
55
54
|
false
|
56
55
|
end
|
@@ -62,9 +61,13 @@ module ActiveHash
|
|
62
61
|
true
|
63
62
|
end
|
64
63
|
|
64
|
+
def to_param
|
65
|
+
id.present? ? id.to_s : nil
|
66
|
+
end
|
67
|
+
|
65
68
|
def persisted?
|
66
69
|
other = self.class.find_by_id(id)
|
67
|
-
other.present?
|
70
|
+
other.present?
|
68
71
|
end
|
69
72
|
|
70
73
|
def eql?(other)
|
@@ -72,5 +75,19 @@ module ActiveHash
|
|
72
75
|
end
|
73
76
|
|
74
77
|
alias == eql?
|
78
|
+
|
79
|
+
private
|
80
|
+
def self.insert_record(record)
|
81
|
+
@records ||= []
|
82
|
+
record.attributes[:id] ||= next_id
|
83
|
+
|
84
|
+
validate_unique_id(record) if dirty
|
85
|
+
mark_dirty
|
86
|
+
|
87
|
+
if record.valid?
|
88
|
+
add_to_record_index({ record.id.to_s => @records.length })
|
89
|
+
@records << record
|
90
|
+
end
|
91
|
+
end
|
75
92
|
end
|
76
93
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ActiveRepository
|
2
|
+
module Writers
|
3
|
+
def find_or_create(attributes)
|
4
|
+
object = get_model_class.where(attributes).first
|
5
|
+
|
6
|
+
object = model_class.create(attributes) if object.nil?
|
7
|
+
|
8
|
+
serialize!(object.attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(attributes={})
|
12
|
+
object = get_model_class.new(attributes)
|
13
|
+
|
14
|
+
object.id = nil if exists?(object.id)
|
15
|
+
|
16
|
+
if get_model_class == self
|
17
|
+
object.save
|
18
|
+
else
|
19
|
+
repository = serialize!(object.attributes)
|
20
|
+
repository.valid? ? (object = get_model_class.create(attributes)) : false
|
21
|
+
end
|
22
|
+
|
23
|
+
serialize!(object.attributes) unless object.class.name == self
|
24
|
+
end
|
25
|
+
|
26
|
+
module InstanceMethods
|
27
|
+
def update_attributes(attributes)
|
28
|
+
object = nil
|
29
|
+
if mongoid?
|
30
|
+
object = self.class.get_model_class.find(self.id)
|
31
|
+
else
|
32
|
+
object = self.class.get_model_class.find(self.id)
|
33
|
+
end
|
34
|
+
|
35
|
+
attributes.each do |k,v|
|
36
|
+
object.update_attribute("#{k.to_s}", v) unless k == :id
|
37
|
+
end
|
38
|
+
|
39
|
+
self.reload
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_attribute(key, value)
|
43
|
+
if self.class == self.class.get_model_class
|
44
|
+
super(key,value)
|
45
|
+
else
|
46
|
+
object = self.class.get_model_class.find(self.id)
|
47
|
+
|
48
|
+
if mongoid?
|
49
|
+
super(key,value)
|
50
|
+
key = key.to_s == 'id' ? '_id' : key.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
object.update_attribute(key, value)
|
54
|
+
object.save
|
55
|
+
end
|
56
|
+
|
57
|
+
self.reload
|
58
|
+
end
|
59
|
+
|
60
|
+
def attributes=(new_attributes)
|
61
|
+
new_attributes.each do |k,v|
|
62
|
+
self.send("#{k.to_s == '_id' ? 'id' : k.to_s}=", v)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|