active_repository 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/efreesen/active_repository.png)](http://travis-ci.org/efreesen/active_repository)[![Dependency Status](https://gemnasium.com/efreesen/active_repository.png)](https://gemnasium.com/efreesen/active_repository) [![Code Climate](https://codeclimate.com/badge.png)](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
|