census 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +5 -0
  3. data/Rakefile +70 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/census/data_groups_controller.rb +44 -0
  6. data/app/helpers/census_helper.rb +15 -0
  7. data/app/models/answer.rb +43 -0
  8. data/app/models/choice.rb +9 -0
  9. data/app/models/data_group.rb +10 -0
  10. data/app/models/question.rb +54 -0
  11. data/app/views/census/_question_fields.html.erb +40 -0
  12. data/app/views/census/_user_answers.html.erb +10 -0
  13. data/app/views/census/_user_questions.html.erb +10 -0
  14. data/app/views/census/data_groups/_choice_fields.html.erb +4 -0
  15. data/app/views/census/data_groups/_form.html.erb +11 -0
  16. data/app/views/census/data_groups/_question_fields.html.erb +22 -0
  17. data/app/views/census/data_groups/edit.html.erb +7 -0
  18. data/app/views/census/data_groups/index.html.erb +10 -0
  19. data/app/views/census/data_groups/new.html.erb +7 -0
  20. data/config/routes.rb +8 -0
  21. data/generators/census/USAGE +1 -0
  22. data/generators/census/census_generator.rb +39 -0
  23. data/generators/census/lib/insert_commands.rb +33 -0
  24. data/generators/census/lib/rake_commands.rb +22 -0
  25. data/generators/census/templates/README +29 -0
  26. data/generators/census/templates/census.js +10 -0
  27. data/generators/census/templates/census.rb +14 -0
  28. data/generators/census/templates/factories.rb +24 -0
  29. data/generators/census/templates/migrations/with_users.rb +60 -0
  30. data/generators/census/templates/migrations/without_users.rb +54 -0
  31. data/generators/census/templates/user.rb +3 -0
  32. data/lib/census/data_type.rb +33 -0
  33. data/lib/census/user.rb +85 -0
  34. data/lib/census.rb +1 -0
  35. data/rails/init.rb +7 -0
  36. data/shoulda_macros/census.rb +35 -0
  37. data/test/controllers/data_groups_controller_test.rb +165 -0
  38. data/test/models/answer_test.rb +44 -0
  39. data/test/models/choice_test.rb +24 -0
  40. data/test/models/data_group_test.rb +12 -0
  41. data/test/models/question_test.rb +213 -0
  42. data/test/models/user_test.rb +9 -0
  43. data/test/rails_root/app/controllers/application_controller.rb +10 -0
  44. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  45. data/test/rails_root/app/models/user.rb +3 -0
  46. data/test/rails_root/config/boot.rb +110 -0
  47. data/test/rails_root/config/environment.rb +8 -0
  48. data/test/rails_root/config/environments/development.rb +17 -0
  49. data/test/rails_root/config/environments/production.rb +28 -0
  50. data/test/rails_root/config/environments/test.rb +32 -0
  51. data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  52. data/test/rails_root/config/initializers/census.rb +14 -0
  53. data/test/rails_root/config/initializers/inflections.rb +10 -0
  54. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  55. data/test/rails_root/config/initializers/new_rails_defaults.rb +21 -0
  56. data/test/rails_root/config/initializers/session_store.rb +15 -0
  57. data/test/rails_root/config/routes.rb +43 -0
  58. data/test/rails_root/db/migrate/20100406160306_create_census_tables.rb +60 -0
  59. data/test/rails_root/db/schema.rb +58 -0
  60. data/test/rails_root/test/factories/census.rb +24 -0
  61. data/test/rails_root/test/performance/browsing_test.rb +9 -0
  62. data/test/rails_root/test/test_helper.rb +38 -0
  63. data/test/rails_root/vendor/gems/acts_as_list-0.1.2/lib/acts_as_list.rb +254 -0
  64. data/test/rails_root/vendor/gems/acts_as_list-0.1.2/test/list_test.rb +369 -0
  65. data/test/rails_root/vendor/gems/inverse_of-0.0.1/install.rb +1 -0
  66. data/test/rails_root/vendor/gems/inverse_of-0.0.1/lib/inverse_of.rb +293 -0
  67. data/test/rails_root/vendor/gems/inverse_of-0.0.1/rails/init.rb +1 -0
  68. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/cases/helper.rb +28 -0
  69. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/cases/inverse_associations_test.rb +567 -0
  70. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/club.rb +13 -0
  71. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/face.rb +7 -0
  72. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/interest.rb +5 -0
  73. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/man.rb +9 -0
  74. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/sponsor.rb +4 -0
  75. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/zine.rb +3 -0
  76. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/schema/schema.rb +32 -0
  77. data/test/rails_root/vendor/gems/inverse_of-0.0.1/uninstall.rb +1 -0
  78. data/test/test_helper.rb +19 -0
  79. metadata +190 -0
@@ -0,0 +1,293 @@
1
+ if ([ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR, ActiveRecord::VERSION::TINY] <=> [2, 3, 6]) < 0
2
+ module InverseOf
3
+ class InverseOfAssociationNotFoundError < ActiveRecord::ActiveRecordError #:nodoc:
4
+ def initialize(reflection, associated_class = nil)
5
+ super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
6
+ end
7
+ end
8
+
9
+ module Reflection
10
+ def self.included(base)
11
+ base::AssociationReflection.send :include, AssociationReflection
12
+ base::ThroughReflection.send :include, ThroughReflection
13
+ end
14
+
15
+ module AssociationReflection
16
+ def self.included(base)
17
+ base.alias_method_chain :check_validity!, :inverse_of
18
+ end
19
+
20
+ def check_validity_with_inverse_of!
21
+ check_validity_of_inverse!
22
+ check_validity_without_inverse_of!
23
+ end
24
+
25
+ def check_validity_of_inverse!
26
+ unless options[:polymorphic]
27
+ if has_inverse? && inverse_of.nil?
28
+ raise InverseOfAssociationNotFoundError.new(self)
29
+ end
30
+ end
31
+ end
32
+
33
+ def has_inverse?
34
+ !@options[:inverse_of].nil?
35
+ end
36
+
37
+ def inverse_of
38
+ if has_inverse?
39
+ @inverse_of ||= klass.reflect_on_association(options[:inverse_of])
40
+ end
41
+ end
42
+
43
+ def polymorphic_inverse_of(associated_class)
44
+ if has_inverse?
45
+ if inverse_relationship = associated_class.reflect_on_association(options[:inverse_of])
46
+ inverse_relationship
47
+ else
48
+ raise InverseOfAssociationNotFoundError.new(self, associated_class)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ module ThroughReflection
55
+ def self.included(base)
56
+ base.alias_method_chain :check_validity!, :inverse_of
57
+ end
58
+
59
+ def check_validity_with_inverse_of!
60
+ check_validity_of_inverse!
61
+ check_validity_without_inverse_of!
62
+ end
63
+ end
64
+ end
65
+
66
+ module Associations
67
+ module AssociationCollection
68
+ def self.included(base)
69
+ base.alias_method_chain :find_target, :inverse_of
70
+ base.alias_method_chain :add_record_to_target_with_callbacks, :inverse_of
71
+ end
72
+
73
+ def find_target_with_inverse_of
74
+ records = find_target_without_inverse_of
75
+ records.each do |record|
76
+ set_inverse_instance(record, @owner)
77
+ end
78
+ records
79
+ end
80
+
81
+ def add_record_to_target_with_callbacks_with_inverse_of(record, &block)
82
+ record = add_record_to_target_with_callbacks_without_inverse_of(record, &block)
83
+ set_inverse_instance(record, @owner)
84
+ record
85
+ end
86
+ end
87
+
88
+ module AssociationProxy
89
+ def self.included(base)
90
+ base.alias_method_chain :initialize, :inverse_of
91
+ end
92
+
93
+ def initialize_with_inverse_of(owner, reflection)
94
+ reflection.check_validity!
95
+ initialize_without_inverse_of(owner, reflection)
96
+ end
97
+
98
+ private
99
+
100
+ def set_inverse_instance(record, instance)
101
+ return if record.nil? || !we_can_set_the_inverse_on_this?(record)
102
+ inverse_relationship = @reflection.inverse_of
103
+ unless inverse_relationship.nil?
104
+ record.send(:"set_#{inverse_relationship.name}_target", instance)
105
+ end
106
+ end
107
+
108
+ # Override in subclasses
109
+ def we_can_set_the_inverse_on_this?(record)
110
+ false
111
+ end
112
+ end
113
+
114
+ module BelongsToAssociation
115
+ def self.included(base)
116
+ base.alias_method_chain :replace, :inverse_of
117
+ base.alias_method_chain :find_target, :inverse_of
118
+ end
119
+
120
+ def replace_with_inverse_of(record)
121
+ replace_without_inverse_of(record)
122
+ set_inverse_instance(record, @owner)
123
+ record
124
+ end
125
+
126
+ def find_target_with_inverse_of
127
+ target = find_target_without_inverse_of and
128
+ set_inverse_instance(target, @owner)
129
+ target
130
+ end
131
+
132
+ # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
133
+ # has_one associations.
134
+ def we_can_set_the_inverse_on_this?(record)
135
+ @reflection.has_inverse? && @reflection.inverse_of.macro == :has_one
136
+ end
137
+ end
138
+
139
+ module BelongsToPolymorphicAssociation
140
+ def self.included(base)
141
+ base.alias_method_chain :replace, :inverse_of
142
+ base.alias_method_chain :find_target, :inverse_of
143
+ end
144
+
145
+ def replace_with_inverse_of(record)
146
+ replace_without_inverse_of(record)
147
+ set_inverse_instance(record, @owner)
148
+ record
149
+ end
150
+
151
+ def find_target_with_inverse_of
152
+ target = find_target_without_inverse_of
153
+ set_inverse_instance(target, @owner)
154
+ target
155
+ end
156
+
157
+ # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
158
+ # has_one associations.
159
+ def we_can_set_the_inverse_on_this?(record)
160
+ if @reflection.has_inverse?
161
+ inverse_association = @reflection.polymorphic_inverse_of(record.class)
162
+ inverse_association && inverse_association.macro == :has_one
163
+ else
164
+ false
165
+ end
166
+ end
167
+
168
+ def set_inverse_instance(record, instance)
169
+ return if record.nil? || !we_can_set_the_inverse_on_this?(record)
170
+ inverse_relationship = @reflection.polymorphic_inverse_of(record.class)
171
+ unless inverse_relationship.nil?
172
+ record.send(:"set_#{inverse_relationship.name}_target", instance)
173
+ end
174
+ end
175
+ end
176
+
177
+ module HasManyAssociation
178
+ def we_can_set_the_inverse_on_this?(record)
179
+ inverse = @reflection.inverse_of
180
+ return !inverse.nil?
181
+ end
182
+ end
183
+
184
+ module HasManyThroughAssociation
185
+ def initialize(owner, reflection)
186
+ super
187
+ end
188
+
189
+ # NOTE - not sure that we can actually cope with inverses here
190
+ def we_can_set_the_inverse_on_this?(record)
191
+ false
192
+ end
193
+ end
194
+
195
+ module HasOneAssociation
196
+ def self.included(base)
197
+ base.alias_method_chain :find_target, :inverse_of
198
+ base.alias_method_chain :new_record, :inverse_of
199
+ base.alias_method_chain :replace, :inverse_of
200
+ end
201
+
202
+ def find_target_with_inverse_of
203
+ target = find_target_without_inverse_of
204
+ set_inverse_instance(target, @owner)
205
+ target
206
+ end
207
+
208
+ def replace_with_inverse_of(record, dont_save = false)
209
+ value = replace_without_inverse_of(record, dont_save)
210
+ set_inverse_instance(record, @owner)
211
+ value
212
+ end
213
+
214
+ private
215
+
216
+ def new_record_with_inverse_of(replace_existing, &block)
217
+ record = new_record_without_inverse_of(replace_existing, &block)
218
+ set_inverse_instance(record, @owner) unless replace_existing
219
+ record
220
+ end
221
+
222
+ def we_can_set_the_inverse_on_this?(record)
223
+ inverse = @reflection.inverse_of
224
+ return !inverse.nil?
225
+ end
226
+ end
227
+
228
+ module ClassMethods
229
+ module JoinDependency
230
+ def self.included(base)
231
+ base.alias_method_chain :construct_association, :inverse_of
232
+ end
233
+
234
+ def construct_association_with_inverse_of(record, join, row)
235
+ association = construct_association_without_inverse_of(record, join, row) or
236
+ return nil
237
+ association_proxy = record.send(join.reflection.name)
238
+ association_proxy.__send__(:set_inverse_instance, association, record)
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ module AssociationPreload
245
+ def self.included(base)
246
+ base.extend ClassMethods
247
+ base.metaclass.alias_method_chain :add_preloaded_records_to_collection, :inverse_of
248
+ base.metaclass.alias_method_chain :set_association_single_records, :inverse_of
249
+ end
250
+
251
+ module ClassMethods
252
+ def add_preloaded_records_to_collection_with_inverse_of(parent_records, reflection_name, associated_record)
253
+ value = add_preloaded_records_to_collection_without_inverse_of(parent_records, reflection_name, associated_record)
254
+ parent_records.each do |parent_record|
255
+ association_proxy = parent_record.send(reflection_name)
256
+ association_proxy.__send__(:set_inverse_instance, associated_record, parent_record)
257
+ end
258
+ value
259
+ end
260
+
261
+ def set_association_single_records_with_inverse_of(id_to_record_map, reflection_name, associated_records, key)
262
+ value = set_association_single_records_without_inverse_of(id_to_record_map, reflection_name, associated_records, key)
263
+ associated_records.each do |associated_record|
264
+ mapped_records = id_to_record_map[associated_record[key].to_s]
265
+ mapped_records.each do |mapped_record|
266
+ association_proxy = mapped_record.send(reflection_name)
267
+ association_proxy.__send__(:set_inverse_instance, associated_record, mapped_record)
268
+ end
269
+ end
270
+ value
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ ActiveRecord::InverseOfAssociationNotFoundError = InverseOf::InverseOfAssociationNotFoundError
277
+ ActiveRecord::Associations::AssociationCollection.send :include, InverseOf::Associations::AssociationCollection
278
+ ActiveRecord::Associations::AssociationProxy.send :include, InverseOf::Associations::AssociationProxy
279
+ ActiveRecord::Associations::BelongsToAssociation.send :include, InverseOf::Associations::BelongsToAssociation
280
+ ActiveRecord::Associations::BelongsToPolymorphicAssociation.send :include, InverseOf::Associations::BelongsToPolymorphicAssociation
281
+ ActiveRecord::Associations::HasManyAssociation.send :include, InverseOf::Associations::HasManyAssociation
282
+ ActiveRecord::Associations::HasManyThroughAssociation.send :include, InverseOf::Associations::HasManyThroughAssociation
283
+ ActiveRecord::Associations::HasOneAssociation.send :include, InverseOf::Associations::HasOneAssociation
284
+ ActiveRecord::Associations::ClassMethods::JoinDependency.send :include, InverseOf::Associations::ClassMethods::JoinDependency
285
+ ActiveRecord::Reflection.send :include, InverseOf::Reflection
286
+ ActiveRecord::Base.send :include, InverseOf::AssociationPreload
287
+
288
+ module ActiveRecord::Associations::ClassMethods
289
+ @@valid_keys_for_has_many_association << :inverse_of
290
+ @@valid_keys_for_has_one_association << :inverse_of
291
+ @@valid_keys_for_belongs_to_association << :inverse_of
292
+ end
293
+ end
@@ -0,0 +1 @@
1
+ require 'inverse_of'
@@ -0,0 +1,28 @@
1
+ require 'test/unit'
2
+ require 'ruby-debug'
3
+ require 'active_record'
4
+ require 'active_record/test_case'
5
+ require 'active_record/fixtures'
6
+
7
+ ROOT = File.dirname(File.dirname(File.dirname(__FILE__)))
8
+
9
+ require "#{ROOT}/rails/init"
10
+
11
+ class ActiveSupport::TestCase
12
+ include ActiveRecord::TestFixtures
13
+
14
+ self.fixture_path = "#{ROOT}/test/fixtures"
15
+ self.use_instantiated_fixtures = false
16
+ self.use_transactional_fixtures = true
17
+
18
+ def create_fixtures(*table_names, &block)
19
+ Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block)
20
+ end
21
+ end
22
+
23
+ ActiveRecord::Base.configurations = {'test' => {'adapter' => "sqlite3", 'database' => ":memory:"}}
24
+ ActiveRecord::Base.establish_connection('test')
25
+ ActiveRecord::Base.connection.instance_eval do
26
+ eval File.read("#{ROOT}/test/schema/schema.rb")
27
+ end
28
+ Dir["#{ROOT}/test/models/*.rb"].each{|path| require path}