sessionm-cassandra_object 2.2.53 → 2.2.54
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/lib/cassandra_object.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module CassandraObject
|
2
|
-
class
|
2
|
+
class CassandraObjectError < StandardError
|
3
3
|
end
|
4
4
|
|
5
|
-
class RecordNotSaved <
|
5
|
+
class RecordNotSaved < CassandraObjectError
|
6
6
|
end
|
7
7
|
|
8
|
-
class RecordNotFound <
|
8
|
+
class RecordNotFound < CassandraObjectError
|
9
9
|
end
|
10
10
|
|
11
|
-
class InvalidKey <
|
11
|
+
class InvalidKey < CassandraObjectError
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'active_support/core_ext/hash/except'
|
2
|
+
require 'active_support/core_ext/object/try'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
5
|
+
|
6
|
+
module CassandraObject
|
7
|
+
module NestedAttributes #:nodoc:
|
8
|
+
class TooManyRecords < CassandraObjectError
|
9
|
+
end
|
10
|
+
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
included do
|
14
|
+
class_inheritable_accessor :nested_attributes_options, :instance_writer => false
|
15
|
+
self.nested_attributes_options = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |_, value| value.blank? } }
|
20
|
+
|
21
|
+
def accepts_nested_attributes_for(*attr_names)
|
22
|
+
options = { :allow_destroy => false, :update_only => false }
|
23
|
+
options.update(attr_names.extract_options!)
|
24
|
+
options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
|
25
|
+
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
|
26
|
+
|
27
|
+
attr_names.each do |association_name|
|
28
|
+
if reflection = reflect_on_association(association_name)
|
29
|
+
reflection.options[:autosave] = true
|
30
|
+
add_autosave_association_callbacks(reflection)
|
31
|
+
nested_attributes_options[association_name.to_sym] = options
|
32
|
+
type = (reflection.collection? ? :collection : :one_to_one)
|
33
|
+
|
34
|
+
# def pirate_attributes=(attributes)
|
35
|
+
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
|
36
|
+
# end
|
37
|
+
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
38
|
+
if method_defined?(:#{association_name}_attributes=)
|
39
|
+
remove_method(:#{association_name}_attributes=)
|
40
|
+
end
|
41
|
+
def #{association_name}_attributes=(attributes)
|
42
|
+
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
|
43
|
+
end
|
44
|
+
eoruby
|
45
|
+
else
|
46
|
+
raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def _destroy
|
53
|
+
marked_for_destruction?
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
UNASSIGNABLE_KEYS = %w( id _destroy )
|
59
|
+
|
60
|
+
def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
|
61
|
+
options = nested_attributes_options[association_name]
|
62
|
+
attributes = attributes.with_indifferent_access
|
63
|
+
check_existing_record = (options[:update_only] || !attributes['id'].blank?)
|
64
|
+
|
65
|
+
if check_existing_record && (record = send(association_name)) &&
|
66
|
+
(options[:update_only] || record.id.to_s == attributes['id'].to_s)
|
67
|
+
assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)
|
68
|
+
|
69
|
+
elsif !attributes['id'].blank?
|
70
|
+
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
71
|
+
|
72
|
+
elsif !reject_new_record?(association_name, attributes)
|
73
|
+
method = "build_#{association_name}"
|
74
|
+
if respond_to?(method)
|
75
|
+
send(method, attributes.except(*UNASSIGNABLE_KEYS))
|
76
|
+
else
|
77
|
+
raise ArgumentError, "Cannot build association #{association_name}. Are you trying to build a polymorphic one-to-one association?"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
|
83
|
+
options = nested_attributes_options[association_name]
|
84
|
+
|
85
|
+
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
|
86
|
+
raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
|
87
|
+
end
|
88
|
+
|
89
|
+
if options[:limit] && attributes_collection.size > options[:limit]
|
90
|
+
raise TooManyRecords, "Maximum #{options[:limit]} records are allowed. Got #{attributes_collection.size} records instead."
|
91
|
+
end
|
92
|
+
|
93
|
+
if attributes_collection.is_a? Hash
|
94
|
+
keys = attributes_collection.keys
|
95
|
+
attributes_collection = if keys.include?('id') || keys.include?(:id)
|
96
|
+
Array.wrap(attributes_collection)
|
97
|
+
else
|
98
|
+
attributes_collection.sort_by { |i, _| i.to_i }.map { |_, attributes| attributes }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
association = send(association_name)
|
103
|
+
|
104
|
+
existing_records = if association.loaded?
|
105
|
+
association.to_a
|
106
|
+
else
|
107
|
+
attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact
|
108
|
+
attribute_ids.present? ? association.all(:conditions => {association.primary_key => attribute_ids}) : []
|
109
|
+
end
|
110
|
+
|
111
|
+
attributes_collection.each do |attributes|
|
112
|
+
attributes = attributes.with_indifferent_access
|
113
|
+
|
114
|
+
if attributes['id'].blank?
|
115
|
+
unless reject_new_record?(association_name, attributes)
|
116
|
+
association.build(attributes.except(*UNASSIGNABLE_KEYS))
|
117
|
+
end
|
118
|
+
|
119
|
+
elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s }
|
120
|
+
association.send(:add_record_to_target_with_callbacks, existing_record) if !association.loaded? && !call_reject_if(association_name, attributes)
|
121
|
+
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
122
|
+
|
123
|
+
else
|
124
|
+
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Updates a record with the +attributes+ or marks it for destruction if
|
130
|
+
# +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
|
131
|
+
def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
|
132
|
+
record.attributes = attributes.except(*UNASSIGNABLE_KEYS)
|
133
|
+
record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy
|
134
|
+
end
|
135
|
+
|
136
|
+
# Determines if a hash contains a truthy _destroy key.
|
137
|
+
def has_destroy_flag?(hash)
|
138
|
+
value = hash['_destroy']
|
139
|
+
if value.is_a?(String) && value.blank?
|
140
|
+
nil
|
141
|
+
else
|
142
|
+
[true, 1, '1', 't', 'T', 'true', 'TRUE'].include?(value)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Determines if a new record should be build by checking for
|
147
|
+
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
|
148
|
+
# association and evaluates to +true+.
|
149
|
+
def reject_new_record?(association_name, attributes)
|
150
|
+
has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
|
151
|
+
end
|
152
|
+
|
153
|
+
def call_reject_if(association_name, attributes)
|
154
|
+
return false if has_destroy_flag?(attributes)
|
155
|
+
case callback = nested_attributes_options[association_name][:reject_if]
|
156
|
+
when Symbol
|
157
|
+
method(callback).arity == 0 ? send(callback) : send(callback, attributes)
|
158
|
+
when Proc
|
159
|
+
callback.call(attributes)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def raise_nested_attributes_record_not_found(association_name, record_id)
|
164
|
+
reflection = self.class.reflect_on_association(association_name)
|
165
|
+
raise RecordNotFound, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
metadata
CHANGED
@@ -1,75 +1,73 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sessionm-cassandra_object
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 2
|
7
|
-
- 2
|
8
|
-
- 53
|
9
|
-
version: 2.2.53
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.2.54
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Michael Koziarski
|
13
9
|
- gotime
|
14
10
|
- sessionm
|
15
11
|
autorequire:
|
16
12
|
bindir: bin
|
17
13
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
dependencies:
|
22
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
date: 2012-05-31 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
23
17
|
name: rails
|
24
|
-
|
25
|
-
|
26
|
-
requirements:
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
27
21
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
segments:
|
30
|
-
- 3
|
31
|
-
- 0
|
32
|
-
- 9
|
22
|
+
- !ruby/object:Gem::Version
|
33
23
|
version: 3.0.9
|
34
24
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: cassandra
|
38
25
|
prerelease: false
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 3.0.9
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: cassandra
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
47
39
|
version: 0.11.3
|
48
40
|
type: :runtime
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: bundler
|
52
41
|
prerelease: false
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.11.3
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: bundler
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
61
55
|
version: 1.0.0
|
62
56
|
type: :development
|
63
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 1.0.0
|
64
64
|
description: Cassandra ActiveModel
|
65
65
|
email: klange@sessionm.com
|
66
66
|
executables: []
|
67
|
-
|
68
67
|
extensions: []
|
69
|
-
|
70
|
-
extra_rdoc_files:
|
68
|
+
extra_rdoc_files:
|
71
69
|
- README.markdown
|
72
|
-
files:
|
70
|
+
files:
|
73
71
|
- .gitignore
|
74
72
|
- CHANGELOG
|
75
73
|
- Gemfile
|
@@ -106,6 +104,7 @@ files:
|
|
106
104
|
- lib/cassandra_object/migrations.rb
|
107
105
|
- lib/cassandra_object/migrations/migration.rb
|
108
106
|
- lib/cassandra_object/mocking.rb
|
107
|
+
- lib/cassandra_object/nested_attributes.rb
|
109
108
|
- lib/cassandra_object/persistence.rb
|
110
109
|
- lib/cassandra_object/railtie.rb
|
111
110
|
- lib/cassandra_object/row_ttl.rb
|
@@ -158,41 +157,31 @@ files:
|
|
158
157
|
- test/types/time_type_test.rb
|
159
158
|
- test/types/utf8_string_type_test.rb
|
160
159
|
- test/validations_test.rb
|
161
|
-
has_rdoc: true
|
162
160
|
homepage: http://github.com/sessionm/cassandra_object
|
163
161
|
licenses: []
|
164
|
-
|
165
162
|
post_install_message:
|
166
163
|
rdoc_options: []
|
167
|
-
|
168
|
-
require_paths:
|
164
|
+
require_paths:
|
169
165
|
- lib
|
170
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
- 1
|
176
|
-
- 9
|
177
|
-
- 2
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ! '>='
|
170
|
+
- !ruby/object:Gem::Version
|
178
171
|
version: 1.9.2
|
179
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
- 1
|
185
|
-
- 3
|
186
|
-
- 5
|
172
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
187
177
|
version: 1.3.5
|
188
178
|
requirements: []
|
189
|
-
|
190
179
|
rubyforge_project:
|
191
|
-
rubygems_version: 1.
|
180
|
+
rubygems_version: 1.8.22
|
192
181
|
signing_key:
|
193
182
|
specification_version: 3
|
194
183
|
summary: Cassandra ActiveModel
|
195
|
-
test_files:
|
184
|
+
test_files:
|
196
185
|
- test/active_model_test.rb
|
197
186
|
- test/attributes_test.rb
|
198
187
|
- test/base_test.rb
|