ripple 0.9.5 → 1.0.0.beta

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.
Files changed (152) hide show
  1. data/.gitignore +32 -0
  2. data/Gemfile +10 -9
  3. data/Guardfile +15 -0
  4. data/Rakefile +11 -40
  5. data/lib/rails/generators/ripple/configuration/configuration_generator.rb +0 -13
  6. data/lib/rails/generators/ripple/configuration/templates/ripple.yml +4 -4
  7. data/lib/rails/generators/ripple/js/js_generator.rb +0 -13
  8. data/lib/rails/generators/ripple/js/templates/js/contrib.js +0 -17
  9. data/lib/rails/generators/ripple/js/templates/js/ripple.js +0 -13
  10. data/lib/rails/generators/ripple/model/model_generator.rb +0 -14
  11. data/lib/rails/generators/ripple/model/templates/model.rb +1 -1
  12. data/lib/rails/generators/ripple/observer/observer_generator.rb +0 -14
  13. data/lib/rails/generators/ripple/test/test_generator.rb +7 -19
  14. data/lib/rails/generators/ripple_generator.rb +1 -14
  15. data/lib/ripple.rb +7 -14
  16. data/lib/ripple/associations.rb +129 -26
  17. data/lib/ripple/associations/embedded.rb +1 -15
  18. data/lib/ripple/associations/instantiators.rb +0 -13
  19. data/lib/ripple/associations/linked.rb +41 -19
  20. data/lib/ripple/associations/many.rb +0 -14
  21. data/lib/ripple/associations/many_embedded_proxy.rb +0 -14
  22. data/lib/ripple/associations/many_linked_proxy.rb +39 -18
  23. data/lib/ripple/associations/many_reference_proxy.rb +93 -0
  24. data/lib/ripple/associations/many_stored_key_proxy.rb +76 -0
  25. data/lib/ripple/associations/one.rb +1 -15
  26. data/lib/ripple/associations/one_embedded_proxy.rb +0 -14
  27. data/lib/ripple/associations/one_key_proxy.rb +58 -0
  28. data/lib/ripple/associations/one_linked_proxy.rb +4 -14
  29. data/lib/ripple/associations/one_stored_key_proxy.rb +43 -0
  30. data/lib/ripple/associations/proxy.rb +8 -14
  31. data/lib/ripple/attribute_methods.rb +19 -17
  32. data/lib/ripple/attribute_methods/dirty.rb +19 -15
  33. data/lib/ripple/attribute_methods/query.rb +0 -14
  34. data/lib/ripple/attribute_methods/read.rb +0 -14
  35. data/lib/ripple/attribute_methods/write.rb +0 -14
  36. data/lib/ripple/callbacks.rb +10 -16
  37. data/lib/ripple/conflict/basic_resolver.rb +82 -0
  38. data/lib/ripple/conflict/document_hooks.rb +20 -0
  39. data/lib/ripple/conflict/resolver.rb +71 -0
  40. data/lib/ripple/conflict/test_helper.rb +33 -0
  41. data/lib/ripple/conversion.rb +0 -14
  42. data/lib/ripple/core_ext.rb +1 -14
  43. data/lib/ripple/core_ext/casting.rb +19 -19
  44. data/lib/ripple/core_ext/object.rb +8 -0
  45. data/lib/ripple/document.rb +21 -16
  46. data/lib/ripple/document/bucket_access.rb +0 -14
  47. data/lib/ripple/document/finders.rb +17 -23
  48. data/lib/ripple/document/key.rb +8 -28
  49. data/lib/ripple/document/link.rb +30 -0
  50. data/lib/ripple/document/persistence.rb +12 -20
  51. data/lib/ripple/embedded_document.rb +10 -15
  52. data/lib/ripple/embedded_document/around_callbacks.rb +18 -0
  53. data/lib/ripple/embedded_document/finders.rb +7 -18
  54. data/lib/ripple/embedded_document/persistence.rb +5 -17
  55. data/lib/ripple/i18n.rb +0 -14
  56. data/lib/ripple/inspection.rb +21 -15
  57. data/lib/ripple/locale/en.yml +9 -13
  58. data/lib/ripple/nested_attributes.rb +33 -39
  59. data/lib/ripple/observable.rb +0 -13
  60. data/lib/ripple/properties.rb +1 -14
  61. data/lib/ripple/property_type_mismatch.rb +0 -14
  62. data/lib/ripple/railtie.rb +4 -14
  63. data/lib/ripple/railties/ripple.rake +86 -0
  64. data/lib/ripple/serialization.rb +11 -11
  65. data/lib/ripple/test_server.rb +36 -0
  66. data/lib/ripple/timestamps.rb +0 -13
  67. data/lib/ripple/translation.rb +4 -14
  68. data/lib/ripple/validations.rb +1 -15
  69. data/lib/ripple/validations/associated_validator.rb +26 -17
  70. data/lib/ripple/version.rb +3 -0
  71. data/ripple.gemspec +24 -35
  72. data/spec/integration/ripple/associations_spec.rb +89 -58
  73. data/spec/integration/ripple/conflict_resolution_spec.rb +298 -0
  74. data/spec/integration/ripple/nested_attributes_spec.rb +19 -19
  75. data/spec/integration/ripple/persistence_spec.rb +15 -34
  76. data/spec/integration/ripple/search_associations_spec.rb +31 -0
  77. data/spec/ripple/associations/many_embedded_proxy_spec.rb +23 -36
  78. data/spec/ripple/associations/many_linked_proxy_spec.rb +133 -45
  79. data/spec/ripple/associations/many_reference_proxy_spec.rb +170 -0
  80. data/spec/ripple/associations/many_stored_key_proxy_spec.rb +158 -0
  81. data/spec/ripple/associations/one_embedded_proxy_spec.rb +24 -37
  82. data/spec/ripple/associations/one_key_proxy_spec.rb +82 -0
  83. data/spec/ripple/associations/one_linked_proxy_spec.rb +22 -23
  84. data/spec/ripple/associations/one_stored_key_proxy_spec.rb +72 -0
  85. data/spec/ripple/associations/proxy_spec.rb +21 -15
  86. data/spec/ripple/associations_spec.rb +54 -23
  87. data/spec/ripple/attribute_methods/dirty_spec.rb +56 -5
  88. data/spec/ripple/attribute_methods_spec.rb +47 -21
  89. data/spec/ripple/bucket_access_spec.rb +4 -17
  90. data/spec/ripple/callbacks_spec.rb +52 -15
  91. data/spec/ripple/conflict/resolver_spec.rb +42 -0
  92. data/spec/ripple/conversion_spec.rb +2 -15
  93. data/spec/ripple/core_ext_spec.rb +12 -15
  94. data/spec/ripple/document/link_spec.rb +67 -0
  95. data/spec/ripple/document_spec.rb +34 -19
  96. data/spec/ripple/embedded_document/finders_spec.rb +12 -19
  97. data/spec/ripple/embedded_document/persistence_spec.rb +20 -26
  98. data/spec/ripple/embedded_document_spec.rb +44 -34
  99. data/spec/ripple/finders_spec.rb +58 -29
  100. data/spec/ripple/inspection_spec.rb +40 -37
  101. data/spec/ripple/key_spec.rb +5 -17
  102. data/spec/ripple/observable_spec.rb +3 -16
  103. data/spec/ripple/persistence_spec.rb +134 -18
  104. data/spec/ripple/properties_spec.rb +21 -15
  105. data/spec/ripple/ripple_spec.rb +1 -14
  106. data/spec/ripple/serialization_spec.rb +16 -17
  107. data/spec/ripple/timestamps_spec.rb +73 -52
  108. data/spec/ripple/validations/associated_validator_spec.rb +69 -25
  109. data/spec/ripple/validations_spec.rb +3 -16
  110. data/spec/spec_helper.rb +17 -18
  111. data/spec/support/associations.rb +1 -1
  112. data/spec/support/associations/proxies.rb +0 -13
  113. data/spec/support/integration_setup.rb +11 -0
  114. data/spec/support/mocks.rb +0 -13
  115. data/spec/support/models.rb +33 -2
  116. data/spec/support/models/address.rb +1 -16
  117. data/spec/support/models/box.rb +7 -14
  118. data/spec/support/models/car.rb +27 -1
  119. data/spec/support/models/cardboard_box.rb +0 -14
  120. data/spec/support/models/clock.rb +6 -15
  121. data/spec/support/models/clock_observer.rb +0 -14
  122. data/spec/support/models/credit_card.rb +5 -0
  123. data/spec/support/models/customer.rb +0 -14
  124. data/spec/support/models/email.rb +0 -14
  125. data/spec/support/models/family.rb +1 -13
  126. data/spec/support/models/favorite.rb +0 -14
  127. data/spec/support/models/invoice.rb +0 -14
  128. data/spec/support/models/late_invoice.rb +0 -14
  129. data/spec/support/models/nested.rb +12 -0
  130. data/spec/support/models/ninja.rb +7 -0
  131. data/spec/support/models/note.rb +0 -14
  132. data/spec/support/models/page.rb +1 -15
  133. data/spec/support/models/paid_invoice.rb +0 -14
  134. data/spec/support/models/post.rb +12 -0
  135. data/spec/support/models/profile.rb +7 -0
  136. data/spec/support/models/subscription.rb +26 -0
  137. data/spec/support/models/tasks.rb +0 -18
  138. data/spec/support/models/team.rb +11 -0
  139. data/spec/support/models/transactions.rb +17 -0
  140. data/spec/support/models/tree.rb +2 -16
  141. data/spec/support/models/user.rb +14 -16
  142. data/spec/support/models/widget.rb +8 -14
  143. data/spec/support/search.rb +14 -0
  144. data/spec/support/test_server.rb +22 -12
  145. data/spec/support/test_server.yml.example +14 -2
  146. metadata +223 -59
  147. data/lib/rails/generators/ripple/test/templates/test_server.rb +0 -46
  148. data/spec/support/models/driver.rb +0 -5
  149. data/spec/support/models/engine.rb +0 -4
  150. data/spec/support/models/passenger.rb +0 -5
  151. data/spec/support/models/seat.rb +0 -4
  152. data/spec/support/models/wheel.rb +0 -5
@@ -1,16 +1,3 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
1
 
15
2
  require 'active_support/concern'
16
3
  require 'active_model/observing'
@@ -1,17 +1,3 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
1
  require 'ripple/core_ext/casting'
16
2
  require 'active_support/core_ext/hash/except'
17
3
  require 'active_support/core_ext/hash/indifferent_access'
@@ -61,6 +47,7 @@ module Ripple
61
47
  # @return [Object] The default value for this property if defined, or nil.
62
48
  def default
63
49
  default = options[:default]
50
+ default = default.dup if default.duplicable?
64
51
 
65
52
  return nil if default.nil?
66
53
  type_cast(default.respond_to?(:call) ? default.call : default)
@@ -1,17 +1,3 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
1
  require 'ripple/translation'
16
2
 
17
3
  module Ripple
@@ -1,23 +1,13 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
1
  require 'rails/railtie'
16
2
 
17
3
  module Ripple
18
4
  # Railtie for automatic initialization of the Ripple framework
19
5
  # during Rails initialization.
20
6
  class Railtie < Rails::Railtie
7
+ rake_tasks do
8
+ load "ripple/railties/ripple.rake"
9
+ end
10
+
21
11
  initializer "ripple.configure_rails_initialization" do
22
12
  if File.exist?(Rails.root + "config/ripple.yml")
23
13
  Ripple.load_configuration Rails.root.join('config', 'ripple.yml'), [Rails.env]
@@ -0,0 +1,86 @@
1
+ require 'ripple/translation'
2
+ require 'riak/cluster'
3
+ require 'pp'
4
+
5
+ namespace :riak do
6
+ task :cluster_created => :rails_env do
7
+ fail Ripple::Translator.t('cluster_not_created') unless cluster.exist?
8
+ end
9
+
10
+ desc "Starts the Riak cluster for the current environment"
11
+ task :start => :cluster_created do
12
+ cluster.start
13
+ end
14
+
15
+ desc "Stops the Riak cluster for the current environment"
16
+ task :stop => :cluster_created do
17
+ cluster.stop
18
+ end
19
+
20
+ desc "Creates a Riak cluster for the current environment in db/, e.g. db/development"
21
+ task :create => :rails_env do
22
+ cluster.create
23
+ end
24
+
25
+ desc "Destroys and recreates the cluster for the current environment."
26
+ task :reset => ['riak:destroy', 'riak:setup']
27
+
28
+ desc "Creates the Riak cluster and loads the seed data."
29
+ task :setup => ["riak:create", "db:seed"]
30
+
31
+ desc "Destroys the generated Riak cluster for the current environment."
32
+ task :destroy => :rails_env do
33
+ cluster.destroy
34
+ end
35
+
36
+ desc "Drops data only from the Riak cluster for the current environment."
37
+ task :drop => :cluster_created do
38
+ cluster.drop
39
+ end
40
+
41
+ namespace :create do
42
+ desc "Creates Riak clusters for all environments defined in config/ripple.yml"
43
+ task :all do
44
+ load_config.each do |env, config|
45
+ cluster(env.to_s, config).create
46
+ end
47
+ end
48
+ end
49
+
50
+ namespace :drop do
51
+ desc "Drops data Riak clusters for all environments defined in config/ripple.yml"
52
+ task :all do
53
+ load_config.each do |env, config|
54
+ c = cluster(env.to_s, config)
55
+ warn Ripple::Translator.t('cluster_not_created') unless c.exist?
56
+ c.drop
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ namespace :db do
63
+ task :create => "riak:create"
64
+ namespace(:create){ task :all => "riak:create:all" }
65
+ task :drop => "riak:drop"
66
+ namespace(:drop) { task :all => "riak:drop:all" }
67
+ task :setup => "riak:setup"
68
+ task :reset => "riak:reset"
69
+ task seed: ['riak:start', 'environment'] do
70
+ Rails.application.load_seed
71
+ end
72
+ end
73
+
74
+ def load_config
75
+ file = Rails.root + "config/ripple.yml"
76
+ raise Ripple::MissingConfiguration, file.to_s unless file.exist?
77
+ YAML.load(ERB.new(file.read).result).with_indifferent_access
78
+ end
79
+
80
+ def cluster(environment=nil, config=nil)
81
+ environment ||= Rails.env
82
+ config ||= load_config[environment]
83
+ root = Rails.root + "db" + environment.to_s
84
+ # TODO: We need to deal with multiple hosts and client ports
85
+ Riak::Cluster.new(config.merge(:root => root.to_s).with_indifferent_access)
86
+ end
@@ -1,16 +1,16 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
1
+ # Copyright 2010-2011 Sean Cribbs and Basho Technologies, Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
14
 
15
15
  require 'active_support/concern'
16
16
  require 'active_model/serialization'
@@ -42,7 +42,7 @@ module Ripple
42
42
 
43
43
  hash = super(options)
44
44
 
45
- hash['key'] = key if respond_to?(:key) and key.present?
45
+ hash['key'] = key if respond_to?(:key) && key.present? && (!options[:except] || !options[:except].map(&:to_s).include?("key"))
46
46
 
47
47
  serializable_add_includes(options) do |association, records, opts|
48
48
  hash[association.to_s] = records.is_a?(Enumerable) ? records.map {|r| r.serializable_hash(opts) } : records.serializable_hash(opts)
@@ -0,0 +1,36 @@
1
+ require 'riak/test_server'
2
+ require 'singleton'
3
+
4
+ module Ripple
5
+ # Extends the {Riak::TestServer} to be aware of the Ripple
6
+ # configuration and adjust settings appropriately. Also simplifies
7
+ # its usage in the generation of test helpers.
8
+ class TestServer < Riak::TestServer
9
+ include Singleton
10
+
11
+ # Creates and starts the test server
12
+ def self.setup
13
+ instance.create
14
+ instance.start
15
+ end
16
+
17
+ # Clears data from the test server
18
+ def self.clear
19
+ instance.drop
20
+ end
21
+
22
+ # @private
23
+ def initialize(options=Ripple.config.dup)
24
+ options[:env] ||= {}
25
+ options[:env][:riak_kv] ||= {}
26
+ options[:env][:riak_kv][:js_source_dir] ||= Ripple.config.delete(:js_source_dir) || (Rails.root + "app/mapreduce").to_s
27
+ options[:env][:riak_kv][:map_cache_size] ||= 0
28
+ options[:env][:riak_core] ||= {}
29
+ options[:env][:riak_core][:http] ||= [ Tuple[Ripple.config[:host], Ripple.config[:http_port]] ]
30
+ options[:env][:riak_kv][:pb_port] ||= Ripple.config[:pb_port]
31
+ options[:env][:riak_kv][:pb_ip] ||= Ripple.config[:host]
32
+ options[:root] ||= (Rails.root + 'tmp/riak_test_server').to_s
33
+ super(options)
34
+ end
35
+ end
36
+ end
@@ -1,16 +1,3 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
1
  require 'active_support/time'
15
2
  require 'active_support/concern'
16
3
 
@@ -1,17 +1,3 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
1
  require 'ripple/i18n'
16
2
  require 'riak/util/translation'
17
3
 
@@ -25,4 +11,8 @@ module Ripple
25
11
  :ripple
26
12
  end
27
13
  end
14
+
15
+ # A dummy object so translations can be accessed without module
16
+ # inclusion.
17
+ Translator = Object.new.tap {|o| o.extend Translation }
28
18
  end
@@ -1,17 +1,3 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
1
  require 'active_support/concern'
16
2
  require 'active_model/validations'
17
3
  require 'ripple/translation'
@@ -64,7 +50,7 @@ module Ripple
64
50
  end
65
51
 
66
52
  # Saves the document and raises {DocumentInvalid} exception if
67
- # validations fail.
53
+ # validations fail.
68
54
  def save!
69
55
  (raise Ripple::DocumentInvalid.new(self) unless save) || true
70
56
  end
@@ -1,28 +1,37 @@
1
- # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- #
15
- # Taken from ActiveRecord::Validations::AssociatedValidators
16
- #
17
1
  require 'active_model/validator'
18
2
 
19
3
  module Ripple
20
4
  module Validations
21
5
  class AssociatedValidator < ActiveModel::EachValidator
6
+ include Translation
22
7
  def validate_each(record, attribute, value)
23
8
  return if (value.is_a?(Array) ? value : [value]).collect{ |r| r.nil? || r.valid? }.all?
24
- record.errors.add(attribute, :invalid, options.merge(:value => value))
9
+ record.errors.add(attribute, error_message_for(attribute, value))
25
10
  end
11
+
12
+ private
13
+
14
+ def error_message_for(attribute, associated_records)
15
+ if associated_records.respond_to?(:each_with_index)
16
+ record_errors = associated_records.enum_for(:each_with_index).collect do |record, index|
17
+ next unless record.errors.any?
18
+
19
+ t("associated_document_error_summary",
20
+ :doc_type => attribute.to_s.singularize,
21
+ :doc_id => index + 1,
22
+ :errors => record.errors.full_messages.to_sentence
23
+ )
24
+ end
25
+ record_errors.compact!
26
+ record_errors.flatten!
27
+
28
+ t("many_association_validation_error",
29
+ :association_errors => record_errors.join('; '))
30
+ else
31
+ t("one_association_validation_error",
32
+ :association_errors => associated_records.errors.full_messages.to_sentence)
33
+ end
34
+ end
26
35
  end
27
36
 
28
37
  module ClassMethods
@@ -0,0 +1,3 @@
1
+ module Ripple
2
+ VERSION = "1.0.0.beta"
3
+ end
@@ -1,39 +1,28 @@
1
- # -*- encoding: utf-8 -*-
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'ripple/version'
2
3
 
3
- Gem::Specification.new do |s|
4
- s.name = %q{ripple}
5
- s.version = "0.9.5"
4
+ Gem::Specification.new do |gem|
5
+ # Meta
6
+ gem.name = "ripple"
7
+ gem.version = Ripple::VERSION
8
+ gem.summary = %Q{ripple is an object-mapper library for Riak, the distributed database by Basho.}
9
+ gem.description = %Q{ripple is an object-mapper library for Riak, the distributed database by Basho. It uses ActiveModel to provide an experience that integrates well with Rails 3 applications.}
10
+ gem.email = ["sean@basho.com"]
11
+ gem.homepage = "http://seancribbs.github.com/ripple"
12
+ gem.authors = ["Sean Cribbs"]
6
13
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
- s.authors = [%q{Sean Cribbs}]
9
- s.date = %q{2011-06-14}
10
- s.description = %q{ripple is an object-mapper library for Riak, the distributed database by Basho. It uses ActiveModel to provide an experience that integrates well with Rails 3 applications.}
11
- s.email = %q{sean@basho.com}
12
- s.files = [%q{Gemfile}, %q{lib/rails/generators/ripple/configuration/configuration_generator.rb}, %q{lib/rails/generators/ripple/configuration/templates/ripple.yml}, %q{lib/rails/generators/ripple/js/js_generator.rb}, %q{lib/rails/generators/ripple/js/templates/js/contrib.js}, %q{lib/rails/generators/ripple/js/templates/js/iso8601.js}, %q{lib/rails/generators/ripple/js/templates/js/ripple.js}, %q{lib/rails/generators/ripple/model/model_generator.rb}, %q{lib/rails/generators/ripple/model/templates/model.rb}, %q{lib/rails/generators/ripple/observer/observer_generator.rb}, %q{lib/rails/generators/ripple/observer/templates/observer.rb}, %q{lib/rails/generators/ripple/test/templates/test_server.rb}, %q{lib/rails/generators/ripple/test/test_generator.rb}, %q{lib/rails/generators/ripple_generator.rb}, %q{lib/ripple/associations/embedded.rb}, %q{lib/ripple/associations/instantiators.rb}, %q{lib/ripple/associations/linked.rb}, %q{lib/ripple/associations/many.rb}, %q{lib/ripple/associations/many_embedded_proxy.rb}, %q{lib/ripple/associations/many_linked_proxy.rb}, %q{lib/ripple/associations/one.rb}, %q{lib/ripple/associations/one_embedded_proxy.rb}, %q{lib/ripple/associations/one_linked_proxy.rb}, %q{lib/ripple/associations/proxy.rb}, %q{lib/ripple/associations.rb}, %q{lib/ripple/attribute_methods/dirty.rb}, %q{lib/ripple/attribute_methods/query.rb}, %q{lib/ripple/attribute_methods/read.rb}, %q{lib/ripple/attribute_methods/write.rb}, %q{lib/ripple/attribute_methods.rb}, %q{lib/ripple/callbacks.rb}, %q{lib/ripple/conversion.rb}, %q{lib/ripple/core_ext/casting.rb}, %q{lib/ripple/core_ext.rb}, %q{lib/ripple/document/bucket_access.rb}, %q{lib/ripple/document/finders.rb}, %q{lib/ripple/document/key.rb}, %q{lib/ripple/document/persistence.rb}, %q{lib/ripple/document.rb}, %q{lib/ripple/embedded_document/finders.rb}, %q{lib/ripple/embedded_document/persistence.rb}, %q{lib/ripple/embedded_document.rb}, %q{lib/ripple/i18n.rb}, %q{lib/ripple/inspection.rb}, %q{lib/ripple/locale/en.yml}, %q{lib/ripple/nested_attributes.rb}, %q{lib/ripple/observable.rb}, %q{lib/ripple/properties.rb}, %q{lib/ripple/property_type_mismatch.rb}, %q{lib/ripple/railtie.rb}, %q{lib/ripple/serialization.rb}, %q{lib/ripple/timestamps.rb}, %q{lib/ripple/translation.rb}, %q{lib/ripple/validations/associated_validator.rb}, %q{lib/ripple/validations.rb}, %q{lib/ripple.rb}, %q{Rakefile}, %q{ripple.gemspec}, %q{spec/fixtures/config.yml}, %q{spec/integration/ripple/associations_spec.rb}, %q{spec/integration/ripple/nested_attributes_spec.rb}, %q{spec/integration/ripple/persistence_spec.rb}, %q{spec/ripple/associations/many_embedded_proxy_spec.rb}, %q{spec/ripple/associations/many_linked_proxy_spec.rb}, %q{spec/ripple/associations/one_embedded_proxy_spec.rb}, %q{spec/ripple/associations/one_linked_proxy_spec.rb}, %q{spec/ripple/associations/proxy_spec.rb}, %q{spec/ripple/associations_spec.rb}, %q{spec/ripple/attribute_methods/dirty_spec.rb}, %q{spec/ripple/attribute_methods_spec.rb}, %q{spec/ripple/bucket_access_spec.rb}, %q{spec/ripple/callbacks_spec.rb}, %q{spec/ripple/conversion_spec.rb}, %q{spec/ripple/core_ext_spec.rb}, %q{spec/ripple/document_spec.rb}, %q{spec/ripple/embedded_document/finders_spec.rb}, %q{spec/ripple/embedded_document/persistence_spec.rb}, %q{spec/ripple/embedded_document_spec.rb}, %q{spec/ripple/finders_spec.rb}, %q{spec/ripple/inspection_spec.rb}, %q{spec/ripple/key_spec.rb}, %q{spec/ripple/observable_spec.rb}, %q{spec/ripple/persistence_spec.rb}, %q{spec/ripple/properties_spec.rb}, %q{spec/ripple/ripple_spec.rb}, %q{spec/ripple/serialization_spec.rb}, %q{spec/ripple/timestamps_spec.rb}, %q{spec/ripple/validations/associated_validator_spec.rb}, %q{spec/ripple/validations_spec.rb}, %q{spec/spec_helper.rb}, %q{spec/support/associations/proxies.rb}, %q{spec/support/associations.rb}, %q{spec/support/mocks.rb}, %q{spec/support/models/address.rb}, %q{spec/support/models/box.rb}, %q{spec/support/models/car.rb}, %q{spec/support/models/cardboard_box.rb}, %q{spec/support/models/clock.rb}, %q{spec/support/models/clock_observer.rb}, %q{spec/support/models/company.rb}, %q{spec/support/models/customer.rb}, %q{spec/support/models/driver.rb}, %q{spec/support/models/email.rb}, %q{spec/support/models/engine.rb}, %q{spec/support/models/family.rb}, %q{spec/support/models/favorite.rb}, %q{spec/support/models/invoice.rb}, %q{spec/support/models/late_invoice.rb}, %q{spec/support/models/note.rb}, %q{spec/support/models/page.rb}, %q{spec/support/models/paid_invoice.rb}, %q{spec/support/models/passenger.rb}, %q{spec/support/models/seat.rb}, %q{spec/support/models/tasks.rb}, %q{spec/support/models/tree.rb}, %q{spec/support/models/user.rb}, %q{spec/support/models/wheel.rb}, %q{spec/support/models/widget.rb}, %q{spec/support/models.rb}, %q{spec/support/test_server.rb}, %q{spec/support/test_server.yml.example}]
13
- s.homepage = %q{http://seancribbs.github.com/ripple}
14
- s.require_paths = [%q{lib}]
15
- s.rubygems_version = %q{1.8.5}
16
- s.summary = %q{ripple is an object-mapper library for Riak, the distributed database by Basho.}
17
- s.test_files = [%q{spec/integration/ripple/associations_spec.rb}, %q{spec/integration/ripple/nested_attributes_spec.rb}, %q{spec/integration/ripple/persistence_spec.rb}, %q{spec/ripple/associations/many_embedded_proxy_spec.rb}, %q{spec/ripple/associations/many_linked_proxy_spec.rb}, %q{spec/ripple/associations/one_embedded_proxy_spec.rb}, %q{spec/ripple/associations/one_linked_proxy_spec.rb}, %q{spec/ripple/associations/proxy_spec.rb}, %q{spec/ripple/associations_spec.rb}, %q{spec/ripple/attribute_methods/dirty_spec.rb}, %q{spec/ripple/attribute_methods_spec.rb}, %q{spec/ripple/bucket_access_spec.rb}, %q{spec/ripple/callbacks_spec.rb}, %q{spec/ripple/conversion_spec.rb}, %q{spec/ripple/core_ext_spec.rb}, %q{spec/ripple/document_spec.rb}, %q{spec/ripple/embedded_document/finders_spec.rb}, %q{spec/ripple/embedded_document/persistence_spec.rb}, %q{spec/ripple/embedded_document_spec.rb}, %q{spec/ripple/finders_spec.rb}, %q{spec/ripple/inspection_spec.rb}, %q{spec/ripple/key_spec.rb}, %q{spec/ripple/observable_spec.rb}, %q{spec/ripple/persistence_spec.rb}, %q{spec/ripple/properties_spec.rb}, %q{spec/ripple/ripple_spec.rb}, %q{spec/ripple/serialization_spec.rb}, %q{spec/ripple/timestamps_spec.rb}, %q{spec/ripple/validations/associated_validator_spec.rb}, %q{spec/ripple/validations_spec.rb}]
14
+ # Deps
15
+ gem.add_development_dependency "rspec", "~>2.6.0"
16
+ gem.add_development_dependency 'rake', '~> 0.8.7'
17
+ gem.add_dependency "riak-client", "~>#{Ripple::VERSION}"
18
+ gem.add_dependency "activesupport", [">= 3.0.0", "< 3.2.0"]
19
+ gem.add_dependency "activemodel", [">= 3.0.0", "< 3.2.0"]
20
+ gem.add_dependency "tzinfo"
18
21
 
19
- if s.respond_to? :specification_version then
20
- s.specification_version = 3
21
-
22
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
23
- s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
24
- s.add_runtime_dependency(%q<riak-client>, ["~> 0.9.5"])
25
- s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
26
- s.add_runtime_dependency(%q<activemodel>, ["~> 3.0.0"])
27
- else
28
- s.add_dependency(%q<rspec>, ["~> 2.4.0"])
29
- s.add_dependency(%q<riak-client>, ["~> 0.9.5"])
30
- s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
31
- s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
32
- end
33
- else
34
- s.add_dependency(%q<rspec>, ["~> 2.4.0"])
35
- s.add_dependency(%q<riak-client>, ["~> 0.9.5"])
36
- s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
37
- s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
38
- end
22
+ # Files
23
+ ignores = File.read(".gitignore").split(/\r?\n/).reject{ |f| f =~ /^(#.+|\s*)$/ }.map {|f| Dir[f] }.flatten
24
+ gem.files = (Dir['**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) }
25
+ gem.test_files = (Dir['spec/**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) }
26
+ # gem.executables = Dir['bin/*'].map { |f| File.basename(f) }
27
+ gem.require_paths = ['lib']
39
28
  end