devise_invitable 2.0.14 → 3.0.1

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +166 -97
  4. data/app/controllers/devise/invitations_controller.rb +8 -2
  5. data/app/controllers/devise_invitable/registrations_controller.rb +15 -10
  6. data/lib/devise_invitable/invitation.rb +89 -0
  7. data/lib/devise_invitable/inviter.rb +23 -1
  8. data/lib/devise_invitable/migrator.rb +113 -0
  9. data/lib/devise_invitable/models.rb +353 -86
  10. data/lib/devise_invitable/rails.rb +10 -0
  11. data/lib/devise_invitable/version.rb +1 -1
  12. data/lib/devise_invitable.rb +40 -4
  13. data/lib/generators/active_record/devise_invitable_install_generator.rb +22 -0
  14. data/lib/generators/active_record/devise_invitable_upgrade_generator.rb +28 -0
  15. data/lib/generators/active_record/templates/create_devise_invitations.rb +23 -0
  16. data/lib/generators/active_record/templates/upgrade_devise_invitations.rb +72 -0
  17. data/lib/generators/devise_invitable/devise_invitable_generator.rb +2 -4
  18. data/lib/generators/devise_invitable/install_generator.rb +8 -10
  19. data/lib/generators/devise_invitable/upgrade_generator.rb +16 -0
  20. data/lib/generators/mongoid/devise_invitable_install_generator.rb +7 -0
  21. data/lib/generators/mongoid/devise_invitable_upgrade_generator.rb +11 -0
  22. data/lib/tasks/devise_invitable_tasks.rake +10 -0
  23. data/test/functional/registrations_controller_test.rb +24 -3
  24. data/test/generators_test.rb +16 -9
  25. data/test/integration/invitation_test.rb +24 -3
  26. data/test/mailers/invitation_mail_test.rb +1 -0
  27. data/test/models/invitable_test.rb +40 -2
  28. data/test/models/separate_invitations_test.rb +181 -0
  29. data/test/models_test.rb +34 -0
  30. data/test/rails_app/app/controllers/boolean_inviter_invitations_controller.rb +11 -0
  31. data/test/rails_app/app/controllers/restricted_invitations_controller.rb +9 -0
  32. data/test/rails_app/app/models/user.rb +8 -2
  33. data/test/rails_app/config/initializers/devise.rb +0 -9
  34. data/test/rails_app/config/routes.rb +2 -0
  35. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +22 -0
  36. data/test/routes_test.rb +6 -0
  37. metadata +26 -13
  38. data/lib/generators/active_record/devise_invitable_generator.rb +0 -19
  39. data/lib/generators/active_record/templates/migration.rb +0 -22
  40. data/lib/generators/mongoid/devise_invitable_generator.rb +0 -8
@@ -0,0 +1,113 @@
1
+ module DeviseInvitable
2
+ class Migrator
3
+ BATCH_SIZE = 1_000
4
+
5
+ LEGACY_FIELDS = %w[
6
+ invitation_token invitation_created_at invitation_sent_at
7
+ invitation_accepted_at invited_by_id invited_by_type
8
+ ].freeze
9
+
10
+ def self.call(model_class)
11
+ new(model_class).call
12
+ end
13
+
14
+ def initialize(model_class)
15
+ unless defined?(Mongoid::Document) && model_class < Mongoid::Document
16
+ raise ArgumentError, 'DeviseInvitable::Migrator only supports Mongoid models'
17
+ end
18
+
19
+ @model_class = model_class
20
+ end
21
+
22
+ def call
23
+ migrated = 0
24
+ each_legacy_resource_batch do |resources|
25
+ migrated_identities = migrated_identities_for(resources)
26
+ resources_to_migrate = resources.reject do |resource|
27
+ migrated_identities.include?(migration_identity(resource))
28
+ end
29
+
30
+ insert_invitations(resources_to_migrate)
31
+ remove_legacy_fields(resources)
32
+ migrated += resources_to_migrate.size
33
+ end
34
+ migrated
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :model_class
40
+
41
+ def resources_with_legacy_invitations
42
+ model_class.where(:invitation_created_at.ne => nil)
43
+ end
44
+
45
+ def each_legacy_resource_batch(&block)
46
+ resources_with_legacy_invitations
47
+ .batch_size(BATCH_SIZE)
48
+ .each_slice(BATCH_SIZE, &block)
49
+ end
50
+
51
+ def migrated_identities_for(resources)
52
+ resource_ids = resources.map(&:id)
53
+ DeviseInvitable::Invitation.where(
54
+ invitable_type: model_class.devise_invitable_base_class.name
55
+ ).in(
56
+ invitable_id: resource_ids
57
+ ).pluck(
58
+ :invitable_id, :invitation_created_at
59
+ ).to_h { |identity| [identity, true] }
60
+ end
61
+
62
+ def migration_identity(resource)
63
+ [resource.id, legacy_value(resource, 'invitation_created_at')]
64
+ end
65
+
66
+ def insert_invitations(resources)
67
+ return if resources.empty?
68
+
69
+ now = Time.now.utc
70
+ attributes = resources.map { |resource| invitation_attributes(resource, now) }
71
+ DeviseInvitable::Invitation.collection.insert_many(attributes)
72
+ end
73
+
74
+ def invitation_attributes(resource, now)
75
+ created_at = legacy_value(resource, 'invitation_created_at')
76
+ invite_key = invite_key_for(resource)
77
+ {
78
+ invitation_token: legacy_value(resource, 'invitation_token'),
79
+ invitation_created_at: created_at,
80
+ invitation_sent_at: legacy_value(resource, 'invitation_sent_at'),
81
+ invitation_accepted_at: legacy_value(resource, 'invitation_accepted_at'),
82
+ resource_created_at: created_at,
83
+ invite_key: invite_key,
84
+ invite_key_digest: DeviseInvitable::Invitation.digest_for(
85
+ model_class.devise_invitable_base_class.name,
86
+ invite_key
87
+ ),
88
+ invitable_type: model_class.devise_invitable_base_class.name,
89
+ invitable_id: resource.id,
90
+ invited_by_type: legacy_value(resource, 'invited_by_type'),
91
+ invited_by_id: legacy_value(resource, 'invited_by_id'),
92
+ created_at: now,
93
+ updated_at: now
94
+ }
95
+ end
96
+
97
+ def invite_key_for(resource)
98
+ model_class.invite_key_fields.each_with_object({}) do |key, values|
99
+ values[key] = resource.public_send(key)
100
+ end
101
+ end
102
+
103
+ def legacy_value(resource, field)
104
+ resource.attributes[field]
105
+ end
106
+
107
+ def remove_legacy_fields(resources)
108
+ return if resources.empty?
109
+
110
+ model_class.in(id: resources.map(&:id)).unset(*LEGACY_FIELDS)
111
+ end
112
+ end
113
+ end