acts_has_many 0.1.3 → 0.1.4
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/README.md +107 -24
- data/lib/acts_has_many/active_record/acts/has_many.rb +228 -75
- data/lib/acts_has_many/version.rb +1 -1
- data/spec/has_many_spec.rb +112 -36
- data/spec/helper.rb +2 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# acts_has_many
|
2
2
|
|
3
|
+
Acts_has_many gem gives functional for clean update elements *has_many* relation
|
4
|
+
(additional is has_many :trhough). The aim is work with has_many relation without gerbage,
|
5
|
+
every record must be used, othervise there will be no record.
|
6
|
+
|
3
7
|
## Installation
|
4
8
|
|
5
9
|
Add this line to your application's Gemfile:
|
@@ -41,6 +45,8 @@ end
|
|
41
45
|
|
42
46
|
|
43
47
|
company = Company.create(:title => 'Microsoft')
|
48
|
+
Company.dependent_relations # => ["users"]
|
49
|
+
Company.compare # => :title
|
44
50
|
|
45
51
|
company.actuale? # => false
|
46
52
|
|
@@ -49,20 +55,20 @@ user = User.create do |user|
|
|
49
55
|
# ...
|
50
56
|
end
|
51
57
|
|
52
|
-
company.actuale?
|
53
|
-
company.actuale?
|
58
|
+
company.actuale? # => true
|
59
|
+
company.actuale? :users # => false ( exclude 1 record of current relation)
|
54
60
|
|
55
|
-
company
|
56
|
-
company.model # => Company
|
57
|
-
company.compare # => :title
|
61
|
+
company # => <Company id: 1, title: "Microsoft">
|
58
62
|
|
59
|
-
company.id # => 1
|
60
63
|
update_id, delete_id = company.has_many_update(data: { title: 'Google'}, relation: :users)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
# or
|
65
|
+
# update_id, delete_id = company.has_many_update({ title: 'Google'}, :users)
|
66
|
+
# or
|
67
|
+
# update_id, delete_id = company.update_with_users({ title: 'Google'})
|
64
68
|
|
65
|
-
#
|
69
|
+
update_id # => 1
|
70
|
+
delete_id # => nil
|
71
|
+
company # => <Company id: 1, title: "Google">
|
66
72
|
|
67
73
|
user2 = User.create do |user|
|
68
74
|
user.company = company
|
@@ -70,36 +76,86 @@ user2 = User.create do |user|
|
|
70
76
|
end
|
71
77
|
|
72
78
|
company.actuale? # => true
|
73
|
-
company.actuale?
|
79
|
+
company.actuale? :users # => true
|
74
80
|
|
75
|
-
#
|
76
|
-
user2.destroy # user will be destroyed, company will rollback (because company is used by other user)
|
81
|
+
# if you want to destroy user
|
82
|
+
# user2.destroy # => user will be destroyed, company will rollback (because company is used by other user)
|
77
83
|
|
78
|
-
company
|
79
|
-
update_id, delete_id = company.has_many_update(
|
80
|
-
update_id
|
81
|
-
delete_id
|
84
|
+
company # => <Company id: 1, title: "Google">
|
85
|
+
update_id, delete_id = company.has_many_update({ title: 'Apple'}, :users)
|
86
|
+
update_id # => 2
|
87
|
+
delete_id # => nil
|
82
88
|
|
83
89
|
user2.company = Company.find(update_id)
|
84
90
|
user2.save
|
85
91
|
|
86
|
-
#
|
87
|
-
user2.destroy # user and company will be destroyed (because company is used only by user2)
|
92
|
+
# if you want to destroy user now
|
93
|
+
# user2.destroy # => user and company will be destroyed (because company is used only by user2)
|
88
94
|
|
89
95
|
Company.all # [#<Company id: 1, title: "Google">, #<Company id: 2, title: "Apple"]
|
90
96
|
|
91
|
-
company.destroy # => false
|
97
|
+
company.destroy # => false (because company is used)
|
92
98
|
|
93
|
-
companu
|
94
|
-
update_id, delete_id = company.has_many_update(
|
99
|
+
companu # => <Company id: 1, title: "Google">
|
100
|
+
update_id, delete_id = company.has_many_update({ title: 'Apple'}, :users)
|
95
101
|
update_id # => 2
|
96
102
|
delete_id # => 1
|
97
103
|
|
98
|
-
|
104
|
+
user2.company = Company.find(update_id)
|
105
|
+
user2.save
|
99
106
|
|
100
107
|
company.destroy # => true
|
101
108
|
|
102
109
|
# this situation with delete_id best way is "company.delete" because you miss unnecessary check actuality
|
110
|
+
|
111
|
+
# if you need update element and you don't care where it uses you can skip relation
|
112
|
+
Company.first.has_many_update({title: "IBM"})
|
113
|
+
# in this case check all relation but if you use this gem you don't have unused record
|
114
|
+
# that why this exampl is equal Company.first_or_create({title: "IBM"})
|
115
|
+
|
116
|
+
|
117
|
+
```
|
118
|
+
### Also you can use has_many_update!
|
119
|
+
```ruby
|
120
|
+
|
121
|
+
user = User.first
|
122
|
+
user.company.has_many_update!({title: "Google"}, user)
|
123
|
+
|
124
|
+
user.reload # becaus variable user have old data
|
125
|
+
user.company # <Company id: 3, title: "Google">
|
126
|
+
# you don't need update user
|
127
|
+
```
|
128
|
+
### Use acts_has_many_for with acts_has_many
|
129
|
+
When use acts_has_many_for you don't need set relation and give parent record in case with has_many_update!
|
130
|
+
```ruby
|
131
|
+
|
132
|
+
class User < ActiveRecord::Base
|
133
|
+
belongs_to :company, dependent: :destroy
|
134
|
+
acts_has_many_for :company
|
135
|
+
end
|
136
|
+
|
137
|
+
class Company < ActiveRecord::Base
|
138
|
+
has_many :users
|
139
|
+
|
140
|
+
acts_has_many # after necessary relation
|
141
|
+
end
|
142
|
+
|
143
|
+
# in this case
|
144
|
+
|
145
|
+
user = User.first
|
146
|
+
company = user.company
|
147
|
+
company.has_many_update!({title: "Google"}) # don't give record user
|
148
|
+
|
149
|
+
user.reload # becaus variable user have old data
|
150
|
+
user.company # <Company id: 3, title: "Google">
|
151
|
+
|
152
|
+
new_id, del_id = user.company.has_many_update({title: "Google"}) # don't give relation
|
153
|
+
|
154
|
+
# in this case has_many_update doesn't know about relation and the same as if you skip relation(see above)
|
155
|
+
new_id, del_id = Company.first.has_many_update({title: "something else"})
|
156
|
+
|
157
|
+
# not work becous has_many_update! doesn't know about parent record
|
158
|
+
Company.first.has_many_update!({title: "something else"})
|
103
159
|
```
|
104
160
|
|
105
161
|
### has_many_update_through used with has_many :through and get array parameters
|
@@ -130,4 +186,31 @@ new_rows, delete_ids = Company.has_many_update_through( update: data, new: date,
|
|
130
186
|
user.companies = new_rows # update user companies
|
131
187
|
|
132
188
|
Company.delete(delete_ids) # for delete_ids from has_many_update_through best way is to use "delete" and miss unnecessary check
|
133
|
-
```
|
189
|
+
```
|
190
|
+
|
191
|
+
|
192
|
+
Contributing
|
193
|
+
------------
|
194
|
+
You can help improve this project.
|
195
|
+
|
196
|
+
Here are some ways *you* can contribute:
|
197
|
+
|
198
|
+
* by using alpha, beta, and prerelease versions
|
199
|
+
* by reporting bugs
|
200
|
+
* by suggesting new features
|
201
|
+
* by writing or editing documentation
|
202
|
+
* by writing specifications
|
203
|
+
* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
|
204
|
+
* by refactoring code
|
205
|
+
* by closing [issues](https://github.com/igor04/acts_has_many/issues)
|
206
|
+
* by reviewing patches
|
207
|
+
|
208
|
+
|
209
|
+
Submitting an Issue
|
210
|
+
-------------------
|
211
|
+
We use the [GitHub issue tracker](https://github.com/igor04/acts_has_many/issues) to track bugs and
|
212
|
+
features. Before submitting a bug report or feature request, check to make sure it hasn't already
|
213
|
+
been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
|
214
|
+
bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any
|
215
|
+
details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
|
216
|
+
operating system. Ideally, a bug report should include a pull request with failing specs.
|
@@ -1,32 +1,112 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Acts #:nodoc:
|
3
3
|
module HasMany
|
4
|
+
|
5
|
+
# class methods for use in model
|
6
|
+
# +acts_has_many_for+
|
7
|
+
# +acts_has_many+
|
8
|
+
#
|
9
|
+
# the last method added:
|
10
|
+
#
|
11
|
+
# class method:
|
12
|
+
# +has_many_through_update+
|
13
|
+
# +dependent_relations+
|
14
|
+
# +compare+
|
15
|
+
#
|
16
|
+
# Instance methods:
|
17
|
+
# +model+
|
18
|
+
# +has_many_update+
|
19
|
+
# +has_many_update!+
|
20
|
+
# +update_with_<relation>+
|
21
|
+
# +actuale?+
|
22
|
+
#
|
23
|
+
# set +before_destroy+ callback;
|
24
|
+
|
4
25
|
def self.included(base)
|
5
26
|
base.extend(ClassMethods)
|
6
27
|
end
|
7
|
-
|
28
|
+
|
29
|
+
#
|
30
|
+
# Acts Has Many gem is for added functional to work
|
31
|
+
# with +has_many+ relation (additional is has_many :trhough)
|
32
|
+
#
|
33
|
+
# +acts_has_many+ and +acts_has_many_for+ are class methods for all model,
|
34
|
+
# and you can use them for connection acts_has_many functional to necessary model
|
35
|
+
# acts_has_many set in model where is has_many relation and
|
36
|
+
# acts_has_many_for in model where use model with acts_has_many
|
37
|
+
#
|
38
|
+
# class Education < ActiveRecord::Base
|
39
|
+
# belongs_to :location
|
40
|
+
# ...
|
41
|
+
# acts_has_many_for :location
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# class Location < ActiveRecord::Base
|
45
|
+
# has_many :educaitons
|
46
|
+
# acts_has_many
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# You can use +acts_has_many+ methods without +acts_has_many_for+
|
50
|
+
#
|
51
|
+
# class Education < ActiveRecord::Base
|
52
|
+
# belongs_to :location
|
53
|
+
# ...
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# class Location < ActiveRecord::Base
|
57
|
+
# has_many :education
|
58
|
+
# acts_has_many
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# in this case you can use nex function:
|
62
|
+
#
|
63
|
+
# education = Education.first
|
64
|
+
# location = education.location # get location from education
|
8
65
|
#
|
9
|
-
#
|
66
|
+
# new_id, del_id = location.has_many_update(data: {title:"Kyiv"}, relation: :educations)
|
67
|
+
# # or simple
|
68
|
+
# new_id, del_id = location.has_many_update({title:"Kyiv"}, :educations)
|
69
|
+
# # or with dinamic methods helper
|
70
|
+
# new_id, del_id = location.update_with_educations {title:"Kyiv"}
|
71
|
+
#
|
72
|
+
# # you can also use has_many_update! which updated relation with parent row without you
|
73
|
+
# location.has_many_update!({title: "Kyiv"}, education)
|
10
74
|
#
|
11
|
-
#
|
12
|
-
#
|
75
|
+
# with usage +acts_has_many_for+ you don't need set relation and give parent row in case with has_many_update!
|
76
|
+
# but you need get row for update get per ralation from parent row (see above with location row) in other case
|
77
|
+
# you can't use it becaus methods will not know about relation and paren row for update it.
|
13
78
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# +compare+
|
18
|
-
# +has_many_update+
|
19
|
-
# +actuale?+
|
79
|
+
# new_id, del_id = location.has_many_update {title:"Kyiv"}
|
80
|
+
# # and
|
81
|
+
# location.has_many_update! {title:"Kyiv"}
|
20
82
|
#
|
21
|
-
# set +before_destroy+ callback;
|
22
|
-
#
|
23
83
|
|
24
84
|
module ClassMethods
|
25
|
-
|
85
|
+
|
86
|
+
#
|
87
|
+
# +acts_has_many_for+: use with +acts_has_many+
|
88
|
+
# use for set link between parent row and child
|
89
|
+
# options: list relations (symbol)
|
90
|
+
#
|
91
|
+
|
92
|
+
def acts_has_many_for(*relations)
|
93
|
+
relations.each do |relation|
|
94
|
+
relation = relation.to_s
|
95
|
+
class_eval <<-EOV
|
96
|
+
def #{relation}
|
97
|
+
row = #{relation.classify}.find #{relation.foreign_key}
|
98
|
+
row.tmp_parrent_id = id
|
99
|
+
row.tmp_current_relation = '#{self.name.tableize}'
|
100
|
+
row
|
101
|
+
end
|
102
|
+
EOV
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
26
106
|
#
|
27
107
|
# +acts_has_many+ - available method in all model and switch on
|
28
108
|
# extension functional in concrete model (need located this method
|
29
|
-
# after
|
109
|
+
# after relation which include in dependence, or anywhere but set depend relation)
|
30
110
|
# options
|
31
111
|
# :compare( symbol, string)- name column for compare with other element in table
|
32
112
|
# :relations( array) - concrete name of depended relation
|
@@ -34,19 +114,18 @@ module ActiveRecord
|
|
34
114
|
#
|
35
115
|
|
36
116
|
def acts_has_many(options = {})
|
37
|
-
|
117
|
+
dependent_relations = []
|
38
118
|
options_default = { compare: :title, through: false }
|
39
119
|
|
40
120
|
options = options_default.merge options
|
41
121
|
|
42
|
-
options[:relations] = self.
|
43
|
-
.
|
44
|
-
.map{|k, v| k} if options[:relations].nil?
|
122
|
+
options[:relations] = self.reflect_on_all_associations(:has_many)
|
123
|
+
.map{|o| o.name} if options[:relations].nil?
|
45
124
|
|
46
125
|
options[:relations].each do |relation|
|
47
|
-
|
126
|
+
dependent_relations << relation.to_s.tableize
|
48
127
|
end
|
49
|
-
|
128
|
+
|
50
129
|
#
|
51
130
|
# +has_many_through_update+ (return array) [ 1 - array objects records, 2 - array delete ids ]
|
52
131
|
# options
|
@@ -88,104 +167,178 @@ module ActiveRecord
|
|
88
167
|
end """
|
89
168
|
end
|
90
169
|
|
170
|
+
# add dinamic methods for example
|
171
|
+
# update_with_<relation>(data) equal has_many_update(data, relation)
|
172
|
+
extend_methods = ''
|
173
|
+
dependent_relations.each do |relation|
|
174
|
+
extend_methods += """
|
175
|
+
def update_with_#{relation}(data)
|
176
|
+
has_many_update data: data, relation: :#{relation}
|
177
|
+
end
|
178
|
+
"""
|
179
|
+
end
|
180
|
+
|
91
181
|
class_eval <<-EOV
|
92
182
|
include ActiveRecord::Acts::HasMany::InstanceMethods
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
183
|
+
class << self
|
184
|
+
def dependent_relations
|
185
|
+
#{dependent_relations}
|
186
|
+
end
|
187
|
+
def compare
|
188
|
+
'#{options[:compare]}'.to_sym
|
189
|
+
end
|
98
190
|
end
|
191
|
+
|
99
192
|
def model
|
100
193
|
#{self}
|
101
|
-
end
|
194
|
+
end
|
102
195
|
|
196
|
+
#{extend_methods}
|
103
197
|
#{has_many_through}
|
104
198
|
|
199
|
+
attr_accessor :tmp_current_relation, :tmp_parrent_id
|
105
200
|
before_destroy :destroy_filter
|
106
201
|
EOV
|
107
202
|
end
|
108
203
|
end
|
109
204
|
|
110
205
|
module InstanceMethods
|
206
|
+
|
207
|
+
#
|
208
|
+
# +has_many_update!+ identicaly to has_many_update but
|
209
|
+
# You can use this method when you use +acts_has_many_for+
|
210
|
+
# and get object for update with help of +relation+ or give parent row
|
211
|
+
# option
|
212
|
+
# data for update
|
213
|
+
# parrent row (maybe miss)
|
214
|
+
#
|
215
|
+
|
216
|
+
def has_many_update!(*data)
|
217
|
+
if data.size == 2
|
218
|
+
self.tmp_current_relation = data[1].class.name.tableize
|
219
|
+
self.tmp_parrent_id = data[1].id
|
220
|
+
end
|
221
|
+
|
222
|
+
if tmp_current_relation.nil? or tmp_parrent_id.nil?
|
223
|
+
p "ArgumentError: 'has_many_update!' don't have data about parent object"
|
224
|
+
p "* maybe you use 'acts_has_many_for' incorrectly"
|
225
|
+
p "* if you don't use 'acts_has_many_for' in parent model you can give parent object"
|
226
|
+
return nil
|
227
|
+
end
|
111
228
|
|
229
|
+
new_id, del_id = has_many_update data[0]
|
230
|
+
parrent = eval(tmp_current_relation.classify).find(tmp_parrent_id)
|
231
|
+
parrent.update_attributes("#{model.name.foreign_key}" => new_id)
|
232
|
+
parrent.save!
|
233
|
+
|
234
|
+
destroy unless del_id.nil?
|
235
|
+
model.find new_id
|
236
|
+
end
|
237
|
+
|
112
238
|
#
|
113
239
|
# +has_many_update+ ( return array) [new_id, del_id]
|
114
|
-
# options
|
240
|
+
# options maybe Hash, or list parameters
|
115
241
|
# :data( type: hash) - data for updte
|
116
|
-
# :relation( type: str, symbol) - modifi with tableize
|
117
|
-
#
|
118
|
-
|
119
|
-
def has_many_update(options)
|
120
|
-
options_default = {
|
121
|
-
:data => { title: "" }
|
122
|
-
}
|
242
|
+
# :relation( type: str, symbol) - modifi with tableize (maybe miss)
|
243
|
+
#
|
123
244
|
|
124
|
-
|
125
|
-
options[:data
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
if actuale? relation: options[:relation]
|
132
|
-
# create new object and finish
|
133
|
-
object = model.where(full_compare).first_or_create(options[:data])
|
134
|
-
object_id = object.id
|
245
|
+
def has_many_update(*options)
|
246
|
+
if options.size == 1 && options[0].include?(:data) && options[0].include?(:relation)
|
247
|
+
data = options[0][:data]
|
248
|
+
relation = options[0][:relation]
|
249
|
+
elsif options.size == 2
|
250
|
+
data = options[0]
|
251
|
+
relation = options[1]
|
135
252
|
else
|
136
|
-
|
137
|
-
|
138
|
-
# set new object and delete old
|
139
|
-
delete_id = (object_id == object_tmp.id) ? nil : object_id
|
140
|
-
object_id = object_tmp.id
|
141
|
-
else
|
142
|
-
# update old object
|
143
|
-
if object_id.nil?
|
144
|
-
object = model.where(full_compare).first_or_create(options[:data])
|
145
|
-
object_id = object.id
|
146
|
-
else
|
147
|
-
if options[:data][compare].empty?
|
148
|
-
delete_id = object_id
|
149
|
-
object_id = nil
|
150
|
-
else
|
151
|
-
update_attributes(options[:data])
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
253
|
+
relation = tmp_current_relation
|
254
|
+
data = options[0]
|
155
255
|
end
|
156
|
-
|
256
|
+
|
257
|
+
data_default = {}
|
258
|
+
data_default[model.compare] = ""
|
259
|
+
data = data_default.merge data
|
260
|
+
|
261
|
+
if relation.blank?
|
262
|
+
p "Notice: 'has_many_update' don't know about current relation, and check all relations"
|
263
|
+
end
|
264
|
+
|
265
|
+
has_many_cleaner data.symbolize_keys, relation
|
157
266
|
end
|
158
267
|
|
159
268
|
#
|
160
269
|
# +actuale?+ - check the acutuality of element in has_many table
|
161
|
-
# options
|
162
|
-
# :relation( string, symbol) - exclude current relation
|
270
|
+
# options maybe Hash, or simple parameter
|
271
|
+
# :relation( string, symbol) - exclude current relation (maybe miss)
|
163
272
|
#
|
164
273
|
|
165
|
-
def actuale? (options
|
274
|
+
def actuale? (options={relation: ""})
|
275
|
+
if options.is_a? Hash and options.include? :relation
|
276
|
+
relation = options[:relation].to_s.tableize
|
277
|
+
else
|
278
|
+
relation = options.to_s.tableize
|
279
|
+
end
|
280
|
+
|
166
281
|
actuale = false
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
if options[:relation].to_s.tableize == relation
|
282
|
+
model.dependent_relations.each do |dependent_relation|
|
283
|
+
tmp = self.send(dependent_relation)
|
284
|
+
if relation == dependent_relation
|
171
285
|
actuale ||= tmp.all.size > 1
|
172
286
|
else
|
173
287
|
actuale ||= tmp.exists?
|
174
288
|
end
|
175
289
|
end
|
176
|
-
|
177
290
|
actuale
|
178
291
|
end
|
179
292
|
end
|
180
|
-
|
293
|
+
|
294
|
+
private
|
295
|
+
|
181
296
|
#
|
182
297
|
# +destroy_filter+ - method for before_destroy, check actuale record and
|
183
298
|
# return true for delete or false for leave
|
184
299
|
#
|
185
|
-
|
300
|
+
|
186
301
|
def destroy_filter
|
187
302
|
not actuale?
|
188
303
|
end
|
304
|
+
|
305
|
+
#
|
306
|
+
# base operations in this gem
|
307
|
+
#
|
308
|
+
|
309
|
+
def has_many_cleaner(data, relation)
|
310
|
+
compare = { model.compare => data[model.compare] }
|
311
|
+
|
312
|
+
object_id = id
|
313
|
+
delete_id = nil
|
314
|
+
|
315
|
+
if actuale? relation
|
316
|
+
# create new object and finish
|
317
|
+
object = model.where(compare).first_or_create(data)
|
318
|
+
object_id = object.id
|
319
|
+
else
|
320
|
+
object_tmp = model.where(compare)[0]
|
321
|
+
unless object_tmp.nil?
|
322
|
+
# set new object and delete old
|
323
|
+
delete_id = (object_id == object_tmp.id) ? nil : object_id
|
324
|
+
object_id = object_tmp.id
|
325
|
+
else
|
326
|
+
# update old object
|
327
|
+
if object_id.nil?
|
328
|
+
object = model.where(compare).first_or_create(data)
|
329
|
+
object_id = object.id
|
330
|
+
else
|
331
|
+
if data[model.compare].blank?
|
332
|
+
delete_id = object_id
|
333
|
+
object_id = nil
|
334
|
+
else
|
335
|
+
update_attributes(data)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
[object_id, delete_id]
|
341
|
+
end
|
189
342
|
end
|
190
343
|
end
|
191
344
|
end
|
data/spec/has_many_spec.rb
CHANGED
@@ -33,39 +33,115 @@ require 'helper'
|
|
33
33
|
|
34
34
|
describe "Initialization tipe #{c}" do
|
35
35
|
describe 'acts_has_many' do
|
36
|
-
|
37
|
-
Location.
|
38
|
-
Experience.
|
36
|
+
context 'update method' do
|
37
|
+
let(:location){Location.create :title => "italy"}
|
38
|
+
let(:experience){Experience.create :location => location, :title => "test experience1"}
|
39
|
+
before :each do
|
40
|
+
Location.delete_all
|
41
|
+
Experience.delete_all
|
42
|
+
end
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
location.id.should == add_loc
|
66
|
-
experience.location.id.should == del_loc
|
67
|
-
end
|
44
|
+
it 'has_many_update(data: data, relation: relation)' do
|
45
|
+
add_loc, del_loc = experience.location.has_many_update(
|
46
|
+
:data => {"title" => "ukraine"}, :relation => "experiences")
|
47
|
+
|
48
|
+
Location.all.size.should == 1
|
49
|
+
location.id.should == add_loc
|
50
|
+
del_loc.should == nil
|
51
|
+
experience.location.title.should == "ukraine"
|
52
|
+
|
53
|
+
Experience.create :location => location, :title => "test experience2"
|
54
|
+
|
55
|
+
add_loc, del_loc = experience.location.has_many_update({"title" => "italy"}, "experiences")
|
56
|
+
|
57
|
+
Location.all.size.should == 2
|
58
|
+
location.id.should_not == add_loc
|
59
|
+
del_loc.should == nil
|
60
|
+
experience.location = Location.find(add_loc)
|
61
|
+
experience.location.title.should == "italy"
|
62
|
+
|
63
|
+
add_loc, del_loc = experience.location.has_many_update({"title" => "ukraine"})
|
64
|
+
|
65
|
+
location.id.should == add_loc
|
66
|
+
experience.location.id.should == del_loc
|
67
|
+
end
|
68
68
|
|
69
|
+
it 'has_many_update!(data)' do
|
70
|
+
# update independent Location
|
71
|
+
new_row = experience.location.has_many_update!({"title" => "ukraine"})
|
72
|
+
|
73
|
+
Location.all.size.should == 1
|
74
|
+
location.id.should == new_row.id
|
75
|
+
experience.location.title.should == "ukraine"
|
76
|
+
|
77
|
+
Experience.create :location => location, :title => "test experience2"
|
78
|
+
|
79
|
+
# don't update and create new Location
|
80
|
+
new_row = experience.location.has_many_update!({"title" => "italy"})
|
81
|
+
|
82
|
+
experience.reload
|
83
|
+
Location.all.size.should == 2
|
84
|
+
location.id.should_not == new_row.id
|
85
|
+
experience.location.title.should == "italy"
|
86
|
+
|
87
|
+
# delete unnecessary Location
|
88
|
+
new_row = experience.location.has_many_update!({"title" => "ukraine"})
|
89
|
+
|
90
|
+
location.id.should == new_row.id
|
91
|
+
Location.all.size.should == 1
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'has_many_update!(data, parent_row)' do
|
95
|
+
# update independent Location
|
96
|
+
new_row = location.has_many_update!({"title" => "ukraine"}, experience)
|
97
|
+
|
98
|
+
Location.all.size.should == 1
|
99
|
+
location.id.should == new_row.id
|
100
|
+
experience.location.title.should == "ukraine"
|
101
|
+
|
102
|
+
Experience.create :location => location, :title => "test experience2"
|
103
|
+
|
104
|
+
# don't update and create new Location
|
105
|
+
new_row = location.has_many_update!({"title" => "italy"}, experience)
|
106
|
+
|
107
|
+
experience.reload
|
108
|
+
Location.all.size.should == 2
|
109
|
+
location.id.should_not == new_row.id
|
110
|
+
experience.location.title.should == "italy"
|
111
|
+
|
112
|
+
# delete unnecessary Location
|
113
|
+
new_row = location.has_many_update!({"title" => "italy"}, Experience.where(location_id: location).first) #becaus experience wos reload
|
114
|
+
|
115
|
+
location.id.should_not == new_row.id
|
116
|
+
location.frozen?.should == true
|
117
|
+
Location.all.size.should == 1
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'update_with_<relation>(data)' do
|
121
|
+
add_loc, del_loc = experience.location.update_with_experiences({"title" => "ukraine"})
|
122
|
+
|
123
|
+
Location.all.size.should == 1
|
124
|
+
location.id.should == add_loc
|
125
|
+
del_loc.should == nil
|
126
|
+
experience.location.title.should == "ukraine"
|
127
|
+
|
128
|
+
Experience.create :location => location, :title => "test experience2"
|
129
|
+
|
130
|
+
add_loc, del_loc = experience.location.update_with_experiences({"title" => "italy"})
|
131
|
+
|
132
|
+
Location.all.size.should == 2
|
133
|
+
location.id.should_not == add_loc
|
134
|
+
del_loc.should == nil
|
135
|
+
experience.location = Location.find(add_loc)
|
136
|
+
experience.location.title.should == "italy"
|
137
|
+
|
138
|
+
add_loc, del_loc = experience.location.update_with_experiences({"title" => "ukraine"})
|
139
|
+
|
140
|
+
location.id.should == add_loc
|
141
|
+
experience.location.id.should == del_loc
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
69
145
|
it 'destroy' do
|
70
146
|
Location.delete_all
|
71
147
|
Experience.delete_all
|
@@ -96,16 +172,17 @@ require 'helper'
|
|
96
172
|
location.actuale?(:relation => "experiences").should == false
|
97
173
|
location.actuale?(:relation => :experiences).should == false
|
98
174
|
location.actuale?(:relation => "Experience").should == false
|
175
|
+
location.actuale?("Experience").should == false
|
99
176
|
|
100
177
|
Experience.create( :title => 'test', :location => location )
|
101
178
|
|
102
179
|
location.actuale?.should == true
|
103
180
|
location.actuale?(:relation => "experiences").should == true
|
181
|
+
location.actuale?(:experiences).should == true
|
104
182
|
end
|
105
183
|
|
106
184
|
it 'compare' do
|
107
|
-
|
108
|
-
location.compare.should == :title
|
185
|
+
Location.compare.should == :title
|
109
186
|
end
|
110
187
|
|
111
188
|
it 'model' do
|
@@ -113,9 +190,8 @@ require 'helper'
|
|
113
190
|
location.model.should == Location
|
114
191
|
end
|
115
192
|
|
116
|
-
it '
|
117
|
-
|
118
|
-
location.depend_relations.should == ['experiences']
|
193
|
+
it 'dependent_relations' do
|
194
|
+
Location.dependent_relations.should == ['experiences']
|
119
195
|
end
|
120
196
|
end
|
121
197
|
end
|
data/spec/helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_has_many
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
113
|
version: '0'
|
114
114
|
requirements: []
|
115
115
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.8.
|
116
|
+
rubygems_version: 1.8.19
|
117
117
|
signing_key:
|
118
118
|
specification_version: 3
|
119
119
|
summary: All records must be used, otherwise they will be deleted. Clear logic with
|