cassandra_object 0.6.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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