cassandra_object 0.6.0.pre

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 (113) hide show
  1. data/lib/cassandra_object/associations/one_to_many.rb +136 -0
  2. data/lib/cassandra_object/associations/one_to_one.rb +77 -0
  3. data/lib/cassandra_object/associations.rb +35 -0
  4. data/lib/cassandra_object/attributes.rb +93 -0
  5. data/lib/cassandra_object/base.rb +104 -0
  6. data/lib/cassandra_object/callbacks.rb +10 -0
  7. data/lib/cassandra_object/collection.rb +8 -0
  8. data/lib/cassandra_object/cursor.rb +86 -0
  9. data/lib/cassandra_object/dirty.rb +27 -0
  10. data/lib/cassandra_object/identity/abstract_key_factory.rb +36 -0
  11. data/lib/cassandra_object/identity/key.rb +20 -0
  12. data/lib/cassandra_object/identity/natural_key_factory.rb +51 -0
  13. data/lib/cassandra_object/identity/uuid_key_factory.rb +37 -0
  14. data/lib/cassandra_object/identity.rb +61 -0
  15. data/lib/cassandra_object/indexes.rb +129 -0
  16. data/lib/cassandra_object/legacy_callbacks.rb +33 -0
  17. data/lib/cassandra_object/migrations.rb +72 -0
  18. data/lib/cassandra_object/mocking.rb +15 -0
  19. data/lib/cassandra_object/persistence.rb +193 -0
  20. data/lib/cassandra_object/serialization.rb +6 -0
  21. data/lib/cassandra_object/type_registration.rb +7 -0
  22. data/lib/cassandra_object/types.rb +128 -0
  23. data/lib/cassandra_object/validation.rb +58 -0
  24. data/lib/cassandra_object.rb +30 -0
  25. data/vendor/active_support_shims.rb +4 -0
  26. data/vendor/activemodel/CHANGELOG +13 -0
  27. data/vendor/activemodel/CHANGES +12 -0
  28. data/vendor/activemodel/MIT-LICENSE +21 -0
  29. data/vendor/activemodel/README +21 -0
  30. data/vendor/activemodel/Rakefile +52 -0
  31. data/vendor/activemodel/activemodel.gemspec +19 -0
  32. data/vendor/activemodel/examples/validations.rb +29 -0
  33. data/vendor/activemodel/lib/active_model/attribute_methods.rb +291 -0
  34. data/vendor/activemodel/lib/active_model/callbacks.rb +91 -0
  35. data/vendor/activemodel/lib/active_model/conversion.rb +8 -0
  36. data/vendor/activemodel/lib/active_model/deprecated_error_methods.rb +33 -0
  37. data/vendor/activemodel/lib/active_model/dirty.rb +126 -0
  38. data/vendor/activemodel/lib/active_model/errors.rb +162 -0
  39. data/vendor/activemodel/lib/active_model/lint.rb +91 -0
  40. data/vendor/activemodel/lib/active_model/locale/en.yml +27 -0
  41. data/vendor/activemodel/lib/active_model/naming.rb +45 -0
  42. data/vendor/activemodel/lib/active_model/observing.rb +191 -0
  43. data/vendor/activemodel/lib/active_model/railtie.rb +2 -0
  44. data/vendor/activemodel/lib/active_model/serialization.rb +30 -0
  45. data/vendor/activemodel/lib/active_model/serializers/json.rb +96 -0
  46. data/vendor/activemodel/lib/active_model/serializers/xml.rb +204 -0
  47. data/vendor/activemodel/lib/active_model/state_machine/event.rb +62 -0
  48. data/vendor/activemodel/lib/active_model/state_machine/machine.rb +75 -0
  49. data/vendor/activemodel/lib/active_model/state_machine/state.rb +47 -0
  50. data/vendor/activemodel/lib/active_model/state_machine/state_transition.rb +40 -0
  51. data/vendor/activemodel/lib/active_model/state_machine.rb +70 -0
  52. data/vendor/activemodel/lib/active_model/test_case.rb +18 -0
  53. data/vendor/activemodel/lib/active_model/translation.rb +44 -0
  54. data/vendor/activemodel/lib/active_model/validations/acceptance.rb +55 -0
  55. data/vendor/activemodel/lib/active_model/validations/confirmation.rb +47 -0
  56. data/vendor/activemodel/lib/active_model/validations/exclusion.rb +42 -0
  57. data/vendor/activemodel/lib/active_model/validations/format.rb +64 -0
  58. data/vendor/activemodel/lib/active_model/validations/inclusion.rb +42 -0
  59. data/vendor/activemodel/lib/active_model/validations/length.rb +117 -0
  60. data/vendor/activemodel/lib/active_model/validations/numericality.rb +111 -0
  61. data/vendor/activemodel/lib/active_model/validations/presence.rb +42 -0
  62. data/vendor/activemodel/lib/active_model/validations/with.rb +59 -0
  63. data/vendor/activemodel/lib/active_model/validations.rb +120 -0
  64. data/vendor/activemodel/lib/active_model/validator.rb +110 -0
  65. data/vendor/activemodel/lib/active_model/version.rb +9 -0
  66. data/vendor/activemodel/lib/active_model.rb +61 -0
  67. data/vendor/activemodel/test/cases/attribute_methods_test.rb +46 -0
  68. data/vendor/activemodel/test/cases/callbacks_test.rb +70 -0
  69. data/vendor/activemodel/test/cases/helper.rb +23 -0
  70. data/vendor/activemodel/test/cases/lint_test.rb +28 -0
  71. data/vendor/activemodel/test/cases/naming_test.rb +28 -0
  72. data/vendor/activemodel/test/cases/observing_test.rb +133 -0
  73. data/vendor/activemodel/test/cases/serializeration/json_serialization_test.rb +83 -0
  74. data/vendor/activemodel/test/cases/serializeration/xml_serialization_test.rb +110 -0
  75. data/vendor/activemodel/test/cases/state_machine/event_test.rb +49 -0
  76. data/vendor/activemodel/test/cases/state_machine/machine_test.rb +43 -0
  77. data/vendor/activemodel/test/cases/state_machine/state_test.rb +72 -0
  78. data/vendor/activemodel/test/cases/state_machine/state_transition_test.rb +84 -0
  79. data/vendor/activemodel/test/cases/state_machine_test.rb +312 -0
  80. data/vendor/activemodel/test/cases/tests_database.rb +37 -0
  81. data/vendor/activemodel/test/cases/translation_test.rb +45 -0
  82. data/vendor/activemodel/test/cases/validations/acceptance_validation_test.rb +71 -0
  83. data/vendor/activemodel/test/cases/validations/conditional_validation_test.rb +141 -0
  84. data/vendor/activemodel/test/cases/validations/confirmation_validation_test.rb +58 -0
  85. data/vendor/activemodel/test/cases/validations/exclusion_validation_test.rb +47 -0
  86. data/vendor/activemodel/test/cases/validations/format_validation_test.rb +118 -0
  87. data/vendor/activemodel/test/cases/validations/i18n_generate_message_validation_test.rb +175 -0
  88. data/vendor/activemodel/test/cases/validations/i18n_validation_test.rb +527 -0
  89. data/vendor/activemodel/test/cases/validations/inclusion_validation_test.rb +71 -0
  90. data/vendor/activemodel/test/cases/validations/length_validation_test.rb +437 -0
  91. data/vendor/activemodel/test/cases/validations/numericality_validation_test.rb +180 -0
  92. data/vendor/activemodel/test/cases/validations/presence_validation_test.rb +70 -0
  93. data/vendor/activemodel/test/cases/validations/with_validation_test.rb +166 -0
  94. data/vendor/activemodel/test/cases/validations_test.rb +215 -0
  95. data/vendor/activemodel/test/config.rb +3 -0
  96. data/vendor/activemodel/test/fixtures/topics.yml +41 -0
  97. data/vendor/activemodel/test/models/contact.rb +7 -0
  98. data/vendor/activemodel/test/models/custom_reader.rb +17 -0
  99. data/vendor/activemodel/test/models/developer.rb +6 -0
  100. data/vendor/activemodel/test/models/person.rb +9 -0
  101. data/vendor/activemodel/test/models/reply.rb +34 -0
  102. data/vendor/activemodel/test/models/topic.rb +9 -0
  103. data/vendor/activemodel/test/models/track_back.rb +4 -0
  104. data/vendor/activemodel/test/schema.rb +14 -0
  105. data/vendor/activesupport/lib/active_support/autoload.rb +48 -0
  106. data/vendor/activesupport/lib/active_support/concern.rb +25 -0
  107. data/vendor/activesupport/lib/active_support/core_ext/array/wrap.rb +20 -0
  108. data/vendor/activesupport/lib/active_support/core_ext/object/blank.rb +58 -0
  109. data/vendor/activesupport/lib/active_support/core_ext/object/tap.rb +6 -0
  110. data/vendor/activesupport/lib/active_support/dependency_module.rb +17 -0
  111. data/vendor/activesupport/lib/active_support/i18n.rb +2 -0
  112. data/vendor/activesupport/lib/active_support/locale/en.yml +33 -0
  113. metadata +230 -0
@@ -0,0 +1,166 @@
1
+ # encoding: utf-8
2
+ require 'cases/helper'
3
+ require 'cases/tests_database'
4
+
5
+ require 'models/topic'
6
+
7
+ class ValidatesWithTest < ActiveRecord::TestCase
8
+ include ActiveModel::TestsDatabase
9
+
10
+ def teardown
11
+ Topic.reset_callbacks(:validate)
12
+ end
13
+
14
+ ERROR_MESSAGE = "Validation error from validator"
15
+ OTHER_ERROR_MESSAGE = "Validation error from other validator"
16
+
17
+ class ValidatorThatAddsErrors < ActiveModel::Validator
18
+ def validate(record)
19
+ record.errors[:base] << ERROR_MESSAGE
20
+ end
21
+ end
22
+
23
+ class OtherValidatorThatAddsErrors < ActiveModel::Validator
24
+ def validate(record)
25
+ record.errors[:base] << OTHER_ERROR_MESSAGE
26
+ end
27
+ end
28
+
29
+ class ValidatorThatDoesNotAddErrors < ActiveModel::Validator
30
+ def validate(record)
31
+ end
32
+ end
33
+
34
+ class ValidatorThatValidatesOptions < ActiveModel::Validator
35
+ def validate(record)
36
+ if options[:field] == :first_name
37
+ record.errors[:base] << ERROR_MESSAGE
38
+ end
39
+ end
40
+ end
41
+
42
+ class ValidatorPerEachAttribute < ActiveModel::EachValidator
43
+ def validate_each(record, attribute, value)
44
+ record.errors[attribute] << "Value is #{value}"
45
+ end
46
+ end
47
+
48
+ class ValidatorCheckValidity < ActiveModel::EachValidator
49
+ def check_validity!
50
+ raise "boom!"
51
+ end
52
+ end
53
+
54
+ test "vaidation with class that adds errors" do
55
+ Topic.validates_with(ValidatorThatAddsErrors)
56
+ topic = Topic.new
57
+ assert !topic.valid?, "A class that adds errors causes the record to be invalid"
58
+ assert topic.errors[:base].include?(ERROR_MESSAGE)
59
+ end
60
+
61
+ test "with a class that returns valid" do
62
+ Topic.validates_with(ValidatorThatDoesNotAddErrors)
63
+ topic = Topic.new
64
+ assert topic.valid?, "A class that does not add errors does not cause the record to be invalid"
65
+ end
66
+
67
+ test "with a class that adds errors on update and a new record" do
68
+ Topic.validates_with(ValidatorThatAddsErrors, :on => :update)
69
+ topic = Topic.new
70
+ assert topic.valid?, "Validation doesn't run on create if 'on' is set to update"
71
+ end
72
+
73
+ test "with a class that adds errors on create and a new record" do
74
+ Topic.validates_with(ValidatorThatAddsErrors, :on => :create)
75
+ topic = Topic.new
76
+ assert !topic.valid?, "Validation does run on create if 'on' is set to create"
77
+ assert topic.errors[:base].include?(ERROR_MESSAGE)
78
+ end
79
+
80
+ test "with multiple classes" do
81
+ Topic.validates_with(ValidatorThatAddsErrors, OtherValidatorThatAddsErrors)
82
+ topic = Topic.new
83
+ assert !topic.valid?
84
+ assert topic.errors[:base].include?(ERROR_MESSAGE)
85
+ assert topic.errors[:base].include?(OTHER_ERROR_MESSAGE)
86
+ end
87
+
88
+ test "with if statements that return false" do
89
+ Topic.validates_with(ValidatorThatAddsErrors, :if => "1 == 2")
90
+ topic = Topic.new
91
+ assert topic.valid?
92
+ end
93
+
94
+ test "with if statements that return true" do
95
+ Topic.validates_with(ValidatorThatAddsErrors, :if => "1 == 1")
96
+ topic = Topic.new
97
+ assert !topic.valid?
98
+ assert topic.errors[:base].include?(ERROR_MESSAGE)
99
+ end
100
+
101
+ test "with unless statements that return true" do
102
+ Topic.validates_with(ValidatorThatAddsErrors, :unless => "1 == 1")
103
+ topic = Topic.new
104
+ assert topic.valid?
105
+ end
106
+
107
+ test "with unless statements that returns false" do
108
+ Topic.validates_with(ValidatorThatAddsErrors, :unless => "1 == 2")
109
+ topic = Topic.new
110
+ assert !topic.valid?
111
+ assert topic.errors[:base].include?(ERROR_MESSAGE)
112
+ end
113
+
114
+ test "passes all configuration options to the validator class" do
115
+ topic = Topic.new
116
+ validator = mock()
117
+ validator.expects(:new).with(:foo => :bar, :if => "1 == 1").returns(validator)
118
+ validator.expects(:validate).with(topic)
119
+
120
+ Topic.validates_with(validator, :if => "1 == 1", :foo => :bar)
121
+ assert topic.valid?
122
+ end
123
+
124
+ test "validates_with with options" do
125
+ Topic.validates_with(ValidatorThatValidatesOptions, :field => :first_name)
126
+ topic = Topic.new
127
+ assert !topic.valid?
128
+ assert topic.errors[:base].include?(ERROR_MESSAGE)
129
+ end
130
+
131
+ test "validates_with each validator" do
132
+ Topic.validates_with(ValidatorPerEachAttribute, :attributes => [:title, :content])
133
+ topic = Topic.new :title => "Title", :content => "Content"
134
+ assert !topic.valid?
135
+ assert_equal ["Value is Title"], topic.errors[:title]
136
+ assert_equal ["Value is Content"], topic.errors[:content]
137
+ end
138
+
139
+ test "each validator checks validity" do
140
+ assert_raise RuntimeError do
141
+ Topic.validates_with(ValidatorCheckValidity, :attributes => [:title])
142
+ end
143
+ end
144
+
145
+ test "each validator expects attributes to be given" do
146
+ assert_raise RuntimeError do
147
+ Topic.validates_with(ValidatorPerEachAttribute)
148
+ end
149
+ end
150
+
151
+ test "each validator skip nil values if :allow_nil is set to true" do
152
+ Topic.validates_with(ValidatorPerEachAttribute, :attributes => [:title, :content], :allow_nil => true)
153
+ topic = Topic.new :content => ""
154
+ assert !topic.valid?
155
+ assert topic.errors[:title].empty?
156
+ assert_equal ["Value is "], topic.errors[:content]
157
+ end
158
+
159
+ test "each validator skip blank values if :allow_blank is set to true" do
160
+ Topic.validates_with(ValidatorPerEachAttribute, :attributes => [:title, :content], :allow_blank => true)
161
+ topic = Topic.new :content => ""
162
+ assert topic.valid?
163
+ assert topic.errors[:title].empty?
164
+ assert topic.errors[:content].empty?
165
+ end
166
+ end
@@ -0,0 +1,215 @@
1
+ # encoding: utf-8
2
+ require 'cases/helper'
3
+ require 'cases/tests_database'
4
+
5
+ require 'models/topic'
6
+ require 'models/reply'
7
+ require 'models/developer'
8
+ require 'models/custom_reader'
9
+
10
+ class ValidationsTest < ActiveModel::TestCase
11
+ include ActiveModel::TestsDatabase
12
+
13
+ # Most of the tests mess with the validations of Topic, so lets repair it all the time.
14
+ # Other classes we mess with will be dealt with in the specific tests
15
+ def teardown
16
+ Topic.reset_callbacks(:validate)
17
+ end
18
+
19
+ def test_single_field_validation
20
+ r = Reply.new
21
+ r.title = "There's no content!"
22
+ assert !r.valid?, "A reply without content shouldn't be saveable"
23
+
24
+ r.content = "Messa content!"
25
+ assert r.valid?, "A reply with content should be saveable"
26
+ end
27
+
28
+ def test_single_attr_validation_and_error_msg
29
+ r = Reply.new
30
+ r.title = "There's no content!"
31
+ assert !r.valid?
32
+ assert r.errors[:content].any?, "A reply without content should mark that attribute as invalid"
33
+ assert_equal ["Empty"], r.errors["content"], "A reply without content should contain an error"
34
+ assert_equal 1, r.errors.count
35
+ end
36
+
37
+ def test_double_attr_validation_and_error_msg
38
+ r = Reply.new
39
+ assert !r.valid?
40
+
41
+ assert r.errors[:title].any?, "A reply without title should mark that attribute as invalid"
42
+ assert_equal ["Empty"], r.errors["title"], "A reply without title should contain an error"
43
+
44
+ assert r.errors[:content].any?, "A reply without content should mark that attribute as invalid"
45
+ assert_equal ["Empty"], r.errors["content"], "A reply without content should contain an error"
46
+
47
+ assert_equal 2, r.errors.count
48
+ end
49
+
50
+ def test_single_error_per_attr_iteration
51
+ r = Reply.new
52
+ r.save
53
+
54
+ errors = []
55
+ r.errors.each {|attr, messages| errors << [attr.to_s, messages] }
56
+
57
+ assert errors.include?(["title", "Empty"])
58
+ assert errors.include?(["content", "Empty"])
59
+ end
60
+
61
+ def test_multiple_errors_per_attr_iteration_with_full_error_composition
62
+ r = Reply.new
63
+ r.title = "Wrong Create"
64
+ r.content = "Mismatch"
65
+ r.save
66
+
67
+ errors = r.errors.to_a
68
+
69
+ assert_equal "Title is Wrong Create", errors[0]
70
+ assert_equal "Title is Content Mismatch", errors[1]
71
+ assert_equal 2, r.errors.count
72
+ end
73
+
74
+ def test_errors_on_nested_attributes_expands_name
75
+ t = Topic.new
76
+ t.errors["replies.name"] << "can't be blank"
77
+ assert_equal ["Replies name can't be blank"], t.errors.full_messages
78
+ end
79
+
80
+ def test_errors_on_base
81
+ r = Reply.new
82
+ r.content = "Mismatch"
83
+ r.save
84
+ r.errors[:base] << "Reply is not dignifying"
85
+
86
+ errors = []
87
+ r.errors.to_a.each { |error| errors << error }
88
+
89
+ assert_equal ["Reply is not dignifying"], r.errors[:base]
90
+
91
+ assert errors.include?("Title Empty")
92
+ assert errors.include?("Reply is not dignifying")
93
+ assert_equal 2, r.errors.count
94
+ end
95
+
96
+ def test_validates_each
97
+ hits = 0
98
+ Topic.validates_each(:title, :content, [:title, :content]) do |record, attr|
99
+ record.errors.add attr, 'gotcha'
100
+ hits += 1
101
+ end
102
+ t = Topic.new("title" => "valid", "content" => "whatever")
103
+ assert !t.save
104
+ assert_equal 4, hits
105
+ assert_equal %w(gotcha gotcha), t.errors[:title]
106
+ assert_equal %w(gotcha gotcha), t.errors[:content]
107
+ end
108
+
109
+ def test_validates_each_custom_reader
110
+ hits = 0
111
+ CustomReader.validates_each(:title, :content, [:title, :content]) do |record, attr|
112
+ record.errors.add attr, 'gotcha'
113
+ hits += 1
114
+ end
115
+ t = CustomReader.new("title" => "valid", "content" => "whatever")
116
+ assert !t.valid?
117
+ assert_equal 4, hits
118
+ assert_equal %w(gotcha gotcha), t.errors[:title]
119
+ assert_equal %w(gotcha gotcha), t.errors[:content]
120
+ end
121
+
122
+ def test_validate_block
123
+ Topic.validate { |topic| topic.errors.add("title", "will never be valid") }
124
+ t = Topic.create("title" => "Title", "content" => "whatever")
125
+ assert !t.valid?
126
+ assert t.errors[:title].any?
127
+ assert_equal ["will never be valid"], t.errors["title"]
128
+ end
129
+
130
+ def test_invalid_validator
131
+ Topic.validate :i_dont_exist
132
+ assert_raise(NameError) { t = Topic.create }
133
+ end
134
+
135
+ def test_errors_to_xml
136
+ r = Reply.new :title => "Wrong Create"
137
+ assert !r.valid?
138
+ xml = r.errors.to_xml(:skip_instruct => true)
139
+ assert_equal "<errors>", xml.first(8)
140
+ assert xml.include?("<error>Title is Wrong Create</error>")
141
+ assert xml.include?("<error>Content Empty</error>")
142
+ end
143
+
144
+ def test_validation_order
145
+ Topic.validates_presence_of :title
146
+ Topic.validates_length_of :title, :minimum => 2
147
+
148
+ t = Topic.new("title" => "")
149
+ assert !t.valid?
150
+ assert_equal "can't be blank", t.errors["title"].first
151
+ Topic.validates_presence_of :title, :author_name
152
+ Topic.validate {|topic| topic.errors.add('author_email_address', 'will never be valid')}
153
+ Topic.validates_length_of :title, :content, :minimum => 2
154
+
155
+ t = Topic.new :title => ''
156
+ assert !t.valid?
157
+
158
+ assert_equal :title, key = t.errors.keys.first
159
+ assert_equal "can't be blank", t.errors[key].first
160
+ assert_equal 'is too short (minimum is 2 characters)', t.errors[key].second
161
+ assert_equal :author_name, key = t.errors.keys.second
162
+ assert_equal "can't be blank", t.errors[key].first
163
+ assert_equal :author_email_address, key = t.errors.keys.third
164
+ assert_equal 'will never be valid', t.errors[key].first
165
+ assert_equal :content, key = t.errors.keys.fourth
166
+ assert_equal 'is too short (minimum is 2 characters)', t.errors[key].first
167
+ end
168
+
169
+ def test_invalid_should_be_the_opposite_of_valid
170
+ Topic.validates_presence_of :title
171
+
172
+ t = Topic.new
173
+ assert t.invalid?
174
+ assert t.errors[:title].any?
175
+
176
+ t.title = 'Things are going to change'
177
+ assert !t.invalid?
178
+ end
179
+
180
+ def test_deprecated_error_messages_on
181
+ Topic.validates_presence_of :title
182
+
183
+ t = Topic.new
184
+ assert t.invalid?
185
+
186
+ [:title, "title"].each do |attribute|
187
+ assert_deprecated { assert_equal "can't be blank", t.errors.on(attribute) }
188
+ end
189
+
190
+ Topic.validates_each(:title) do |record, attribute|
191
+ record.errors[attribute] << "invalid"
192
+ end
193
+
194
+ assert t.invalid?
195
+
196
+ [:title, "title"].each do |attribute|
197
+ assert_deprecated do
198
+ assert t.errors.on(attribute).include?("invalid")
199
+ assert t.errors.on(attribute).include?("can't be blank")
200
+ end
201
+ end
202
+ end
203
+
204
+ def test_deprecated_errors_on_base_and_each
205
+ t = Topic.new
206
+ assert t.valid?
207
+
208
+ assert_deprecated { t.errors.add_to_base "invalid topic" }
209
+ assert_deprecated { assert_equal "invalid topic", t.errors.on_base }
210
+ assert_deprecated { assert t.errors.invalid?(:base) }
211
+
212
+ all_errors = t.errors.to_a
213
+ assert_deprecated { assert_equal all_errors, t.errors.each_full{|err| err} }
214
+ end
215
+ end
@@ -0,0 +1,3 @@
1
+ TEST_ROOT = File.expand_path(File.dirname(__FILE__))
2
+ FIXTURES_ROOT = TEST_ROOT + "/fixtures"
3
+ SCHEMA_FILE = TEST_ROOT + "/schema.rb"
@@ -0,0 +1,41 @@
1
+ first:
2
+ id: 1
3
+ title: The First Topic
4
+ author_name: David
5
+ author_email_address: david@loudthinking.com
6
+ written_on: 2003-07-16t15:28:11.2233+01:00
7
+ last_read: 2004-04-15
8
+ bonus_time: 2005-01-30t15:28:00.00+01:00
9
+ content: Have a nice day
10
+ approved: false
11
+ replies_count: 1
12
+
13
+ second:
14
+ id: 2
15
+ title: The Second Topic of the day
16
+ author_name: Mary
17
+ written_on: 2004-07-15t15:28:00.0099+01:00
18
+ content: Have a nice day
19
+ approved: true
20
+ replies_count: 0
21
+ parent_id: 1
22
+ type: Reply
23
+
24
+ third:
25
+ id: 3
26
+ title: The Third Topic of the day
27
+ author_name: Nick
28
+ written_on: 2005-07-15t15:28:00.0099+01:00
29
+ content: I'm a troll
30
+ approved: true
31
+ replies_count: 1
32
+
33
+ fourth:
34
+ id: 4
35
+ title: The Fourth Topic of the day
36
+ author_name: Carl
37
+ written_on: 2006-07-15t15:28:00.0099+01:00
38
+ content: Why not?
39
+ approved: true
40
+ type: Reply
41
+ parent_id: 3
@@ -0,0 +1,7 @@
1
+ class Contact
2
+ attr_accessor :name, :age, :created_at, :awesome, :preferences
3
+
4
+ def initialize(options = {})
5
+ options.each { |name, value| send("#{name}=", value) }
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ class CustomReader
2
+ include ActiveModel::Validations
3
+
4
+ def initialize(data = {})
5
+ @data = data
6
+ end
7
+
8
+ def []=(key, value)
9
+ @data[key] = value
10
+ end
11
+
12
+ private
13
+
14
+ def read_attribute_for_validation(key)
15
+ @data[key]
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ class Developer < ActiveRecord::Base
2
+ validates_inclusion_of :salary, :in => 50000..200000
3
+ validates_length_of :name, :within => 3..20
4
+
5
+ attr_accessor :name_confirmation
6
+ end
@@ -0,0 +1,9 @@
1
+ class Person
2
+ include ActiveModel::Validations
3
+ extend ActiveModel::Translation
4
+
5
+ attr_accessor :title, :karma, :salary
6
+ end
7
+
8
+ class Child < Person
9
+ end
@@ -0,0 +1,34 @@
1
+ require 'models/topic'
2
+
3
+ class Reply < Topic
4
+ validate :errors_on_empty_content
5
+ validate :title_is_wrong_create, :on => :create
6
+
7
+ validate :check_empty_title
8
+ validate :check_content_mismatch, :on => :create
9
+ validate :check_wrong_update, :on => :update
10
+
11
+ attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read
12
+
13
+ def check_empty_title
14
+ errors[:title] << "Empty" unless attribute_present?("title")
15
+ end
16
+
17
+ def errors_on_empty_content
18
+ errors[:content] << "Empty" unless attribute_present?("content")
19
+ end
20
+
21
+ def check_content_mismatch
22
+ if attribute_present?("title") && attribute_present?("content") && content == "Mismatch"
23
+ errors[:title] << "is Content Mismatch"
24
+ end
25
+ end
26
+
27
+ def title_is_wrong_create
28
+ errors[:title] << "is Wrong Create" if attribute_present?("title") && title == "Wrong Create"
29
+ end
30
+
31
+ def check_wrong_update
32
+ errors[:title] << "is Wrong Update" if attribute_present?("title") && title == "Wrong Update"
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ class Topic < ActiveRecord::Base
2
+ def condition_is_true
3
+ true
4
+ end
5
+
6
+ def condition_is_true_but_its_not
7
+ false
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ class Post
2
+ class TrackBack
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :topics, :force => true do |t|
3
+ t.string :title
4
+ t.string :author_name
5
+ t.text :content
6
+ t.boolean :approved, :default => true
7
+ t.string :type
8
+ end
9
+
10
+ create_table :developers, :force => true do |t|
11
+ t.string :name
12
+ t.float :salary
13
+ end
14
+ end
@@ -0,0 +1,48 @@
1
+
2
+ module ActiveSupport
3
+ module Autoload
4
+ @@autoloads = {}
5
+ @@under_path = nil
6
+ @@at_path = nil
7
+ @@eager_autoload = false
8
+
9
+ def autoload(const_name, path = @@at_path)
10
+ full = [self.name, @@under_path, const_name.to_s, path].compact.join("::")
11
+ location = path || Inflector.underscore(full)
12
+
13
+ if @@eager_autoload
14
+ @@autoloads[const_name] = location
15
+ end
16
+ super const_name, location
17
+ end
18
+
19
+ def autoload_under(path)
20
+ @@under_path, old_path = path, @@under_path
21
+ yield
22
+ ensure
23
+ @@under_path = old_path
24
+ end
25
+
26
+ def autoload_at(path)
27
+ @@at_path, old_path = path, @@at_path
28
+ yield
29
+ ensure
30
+ @@at_path = old_path
31
+ end
32
+
33
+ def eager_autoload
34
+ old_eager, @@eager_autoload = @@eager_autoload, true
35
+ yield
36
+ ensure
37
+ @@eager_autoload = old_eager
38
+ end
39
+
40
+ def self.eager_autoload!
41
+ @@autoloads.values.each { |file| require file }
42
+ end
43
+
44
+ def autoloads
45
+ @@autoloads
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_support/dependency_module'
2
+
3
+ module ActiveSupport
4
+ module Concern
5
+ include DependencyModule
6
+
7
+ def append_features(base)
8
+ if super
9
+ base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
10
+ base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods")
11
+ base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
12
+ end
13
+ end
14
+
15
+ def included(base = nil, &block)
16
+ if base.nil?
17
+ @_included_block = block
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ alias_method :include, :depends_on
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ unless Array.respond_to?(:wrap)
2
+ class Array
3
+ # Wraps the object in an Array unless it's an Array. Converts the
4
+ # object to an Array using #to_ary if it implements that.
5
+ def self.wrap(object)
6
+ case object
7
+ when nil
8
+ []
9
+ when self
10
+ object
11
+ else
12
+ if object.respond_to?(:to_ary)
13
+ object.to_ary
14
+ else
15
+ [object]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,58 @@
1
+ class Object
2
+ # An object is blank if it's false, empty, or a whitespace string.
3
+ # For example, "", " ", +nil+, [], and {} are blank.
4
+ #
5
+ # This simplifies
6
+ #
7
+ # if !address.nil? && !address.empty?
8
+ #
9
+ # to
10
+ #
11
+ # if !address.blank?
12
+ def blank?
13
+ respond_to?(:empty?) ? empty? : !self
14
+ end
15
+
16
+ # An object is present if it's not blank.
17
+ def present?
18
+ !blank?
19
+ end
20
+ end
21
+
22
+ class NilClass #:nodoc:
23
+ def blank?
24
+ true
25
+ end
26
+ end
27
+
28
+ class FalseClass #:nodoc:
29
+ def blank?
30
+ true
31
+ end
32
+ end
33
+
34
+ class TrueClass #:nodoc:
35
+ def blank?
36
+ false
37
+ end
38
+ end
39
+
40
+ class Array #:nodoc:
41
+ alias_method :blank?, :empty?
42
+ end
43
+
44
+ class Hash #:nodoc:
45
+ alias_method :blank?, :empty?
46
+ end
47
+
48
+ class String #:nodoc:
49
+ def blank?
50
+ self !~ /\S/
51
+ end
52
+ end
53
+
54
+ class Numeric #:nodoc:
55
+ def blank?
56
+ false
57
+ end
58
+ end