census 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +5 -0
- data/Rakefile +70 -0
- data/VERSION +1 -0
- data/app/controllers/census/data_groups_controller.rb +44 -0
- data/app/helpers/census_helper.rb +15 -0
- data/app/models/answer.rb +43 -0
- data/app/models/choice.rb +9 -0
- data/app/models/data_group.rb +10 -0
- data/app/models/question.rb +54 -0
- data/app/views/census/_question_fields.html.erb +40 -0
- data/app/views/census/_user_answers.html.erb +10 -0
- data/app/views/census/_user_questions.html.erb +10 -0
- data/app/views/census/data_groups/_choice_fields.html.erb +4 -0
- data/app/views/census/data_groups/_form.html.erb +11 -0
- data/app/views/census/data_groups/_question_fields.html.erb +22 -0
- data/app/views/census/data_groups/edit.html.erb +7 -0
- data/app/views/census/data_groups/index.html.erb +10 -0
- data/app/views/census/data_groups/new.html.erb +7 -0
- data/config/routes.rb +8 -0
- data/generators/census/USAGE +1 -0
- data/generators/census/census_generator.rb +39 -0
- data/generators/census/lib/insert_commands.rb +33 -0
- data/generators/census/lib/rake_commands.rb +22 -0
- data/generators/census/templates/README +29 -0
- data/generators/census/templates/census.js +10 -0
- data/generators/census/templates/census.rb +14 -0
- data/generators/census/templates/factories.rb +24 -0
- data/generators/census/templates/migrations/with_users.rb +60 -0
- data/generators/census/templates/migrations/without_users.rb +54 -0
- data/generators/census/templates/user.rb +3 -0
- data/lib/census/data_type.rb +33 -0
- data/lib/census/user.rb +85 -0
- data/lib/census.rb +1 -0
- data/rails/init.rb +7 -0
- data/shoulda_macros/census.rb +35 -0
- data/test/controllers/data_groups_controller_test.rb +165 -0
- data/test/models/answer_test.rb +44 -0
- data/test/models/choice_test.rb +24 -0
- data/test/models/data_group_test.rb +12 -0
- data/test/models/question_test.rb +213 -0
- data/test/models/user_test.rb +9 -0
- data/test/rails_root/app/controllers/application_controller.rb +10 -0
- data/test/rails_root/app/helpers/application_helper.rb +3 -0
- data/test/rails_root/app/models/user.rb +3 -0
- data/test/rails_root/config/boot.rb +110 -0
- data/test/rails_root/config/environment.rb +8 -0
- data/test/rails_root/config/environments/development.rb +17 -0
- data/test/rails_root/config/environments/production.rb +28 -0
- data/test/rails_root/config/environments/test.rb +32 -0
- data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_root/config/initializers/census.rb +14 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/initializers/new_rails_defaults.rb +21 -0
- data/test/rails_root/config/initializers/session_store.rb +15 -0
- data/test/rails_root/config/routes.rb +43 -0
- data/test/rails_root/db/migrate/20100406160306_create_census_tables.rb +60 -0
- data/test/rails_root/db/schema.rb +58 -0
- data/test/rails_root/test/factories/census.rb +24 -0
- data/test/rails_root/test/performance/browsing_test.rb +9 -0
- data/test/rails_root/test/test_helper.rb +38 -0
- data/test/rails_root/vendor/gems/acts_as_list-0.1.2/lib/acts_as_list.rb +254 -0
- data/test/rails_root/vendor/gems/acts_as_list-0.1.2/test/list_test.rb +369 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/install.rb +1 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/lib/inverse_of.rb +293 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/rails/init.rb +1 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/cases/helper.rb +28 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/cases/inverse_associations_test.rb +567 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/club.rb +13 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/face.rb +7 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/interest.rb +5 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/man.rb +9 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/sponsor.rb +4 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/zine.rb +3 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/schema/schema.rb +32 -0
- data/test/rails_root/vendor/gems/inverse_of-0.0.1/uninstall.rb +1 -0
- data/test/test_helper.rb +19 -0
- 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}
|