canvas_sync 0.10.6 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/canvas_sync.rb +10 -0
- data/lib/canvas_sync/api_syncable.rb +8 -0
- data/lib/canvas_sync/generators/templates/migrations/create_admins.rb +7 -4
- data/lib/canvas_sync/generators/templates/migrations/create_roles.rb +3 -4
- data/lib/canvas_sync/generators/templates/models/account.rb +2 -0
- data/lib/canvas_sync/generators/templates/models/admin.rb +4 -5
- data/lib/canvas_sync/generators/templates/models/role.rb +0 -4
- data/lib/canvas_sync/generators/templates/models/term.rb +0 -2
- data/lib/canvas_sync/job.rb +10 -0
- data/lib/canvas_sync/jobs/sync_admins_job.rb +9 -5
- data/lib/canvas_sync/jobs/sync_roles_job.rb +8 -5
- data/lib/canvas_sync/jobs/sync_terms_job.rb +8 -2
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +2 -1
- data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +2 -1
- data/spec/canvas_sync/models/admins_spec.rb +3 -5
- data/spec/canvas_sync/models/roles_spec.rb +5 -5
- data/spec/canvas_sync/models/term_spec.rb +3 -3
- data/spec/dummy/app/models/account.rb +2 -0
- data/spec/dummy/app/models/admin.rb +4 -5
- data/spec/dummy/app/models/role.rb +0 -4
- data/spec/dummy/app/models/term.rb +0 -2
- data/spec/dummy/db/migrate/{20190702203628_create_roles.rb → 20190927204545_create_roles.rb} +3 -4
- data/spec/dummy/db/migrate/{20190702203629_create_admins.rb → 20190927204546_create_admins.rb} +7 -4
- data/spec/dummy/db/schema.rb +11 -9
- data/spec/factories/admin_factory.rb +0 -1
- data/spec/support/fake_canvas.rb +2 -2
- data/spec/support/fixtures/canvas_responses/roles.json +6 -0
- metadata +10 -21
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -4188
- data/spec/dummy/log/test.log +0 -71696
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +0 -3
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4445382aaee8091e3d40bc0f836bfeaef14d99d1
|
4
|
+
data.tar.gz: fa0ff09fd9f2132ab29fb80a95c1353e38f2bbd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3acfbb161a7c11a8d2b6c093b52b55ef5b0bf82876ff0a8e28b0092753d56ea2b28f6fa65360bb4889f5145361897e45e813acd000e45b84f9e6e9b27ab538fa
|
7
|
+
data.tar.gz: be69604343fe4458a9e5cac5d26a8e307b909e3a2e2693d6aa9bdab38c5e3271cc73dab72f8d98959a92b0ef7b515d634c7f62701d61b9681e4f40b6abb17857
|
data/lib/canvas_sync.rb
CHANGED
@@ -138,6 +138,16 @@ module CanvasSync
|
|
138
138
|
sub_items
|
139
139
|
end
|
140
140
|
|
141
|
+
# Given a Model or Relation, scope it down to items that should be synced
|
142
|
+
def sync_scope(scope)
|
143
|
+
terms = %i[should_canvas_sync active_for_canvas_sync should_sync active_for_sync active]
|
144
|
+
terms.each do |t|
|
145
|
+
return scope.send(t) if scope.respond_to?(t)
|
146
|
+
end
|
147
|
+
Rails.logger.warn("Could not filter Syncable Scope for model '#{scope.try(:model)&.name || scope.name}'")
|
148
|
+
scope
|
149
|
+
end
|
150
|
+
|
141
151
|
# Syn any report to an specific set of models
|
142
152
|
#
|
143
153
|
# @param reports_mapping [Array<Hash>] List of reports with their specific model and params
|
@@ -21,6 +21,14 @@ module CanvasSync::ApiSyncable
|
|
21
21
|
inst
|
22
22
|
end
|
23
23
|
|
24
|
+
def create_or_update_from_api_params(api_params)
|
25
|
+
api_params = api_params.with_indifferent_access
|
26
|
+
inst = find_or_initialize_by(canvas_id: api_params[:id])
|
27
|
+
inst.update_from_api_params(api_params)
|
28
|
+
inst.save! if inst.changed?
|
29
|
+
inst
|
30
|
+
end
|
31
|
+
|
24
32
|
def api_sync_options=(opts)
|
25
33
|
@api_sync_options = opts
|
26
34
|
end
|
@@ -5,13 +5,16 @@ class CreateAdmins < ActiveRecord::Migration[5.1]
|
|
5
5
|
create_table :admins do |t|
|
6
6
|
t.bigint :canvas_id, null: false
|
7
7
|
t.string :role_name
|
8
|
-
t.bigint :
|
9
|
-
t.
|
10
|
-
t.bigint :canvas_user_id
|
11
|
-
t.string :workflow_state
|
8
|
+
t.bigint :canvas_account_id
|
9
|
+
t.bigint :canvas_role_id
|
10
|
+
t.bigint :canvas_user_id
|
11
|
+
t.string :workflow_state
|
12
12
|
|
13
13
|
t.timestamps
|
14
14
|
end
|
15
15
|
add_index :admins, :canvas_id, unique: true
|
16
|
+
add_index :admins, :canvas_role_id
|
17
|
+
add_index :admins, :canvas_user_id
|
18
|
+
add_index :admins, :canvas_account_id
|
16
19
|
end
|
17
20
|
end
|
@@ -4,11 +4,10 @@ class CreateRoles < ActiveRecord::Migration[5.1]
|
|
4
4
|
def change
|
5
5
|
create_table :roles do |t|
|
6
6
|
t.integer :canvas_id, null: false
|
7
|
-
t.string :label
|
8
|
-
t.string :base_role_type
|
9
|
-
t.json :account
|
7
|
+
t.string :label
|
8
|
+
t.string :base_role_type
|
10
9
|
t.integer :canvas_account_id
|
11
|
-
t.string :workflow_state
|
10
|
+
t.string :workflow_state
|
12
11
|
t.json :permissions
|
13
12
|
|
14
13
|
t.timestamps
|
@@ -4,6 +4,7 @@ class Admin < ApplicationRecord
|
|
4
4
|
include CanvasSync::ApiSyncable
|
5
5
|
|
6
6
|
validates :canvas_id, uniqueness: true, presence: true
|
7
|
+
belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
|
7
8
|
belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
|
8
9
|
belongs_to :role, primary_key: :canvas_id, foreign_key: :canvas_role_id, optional: true
|
9
10
|
|
@@ -11,16 +12,14 @@ class Admin < ApplicationRecord
|
|
11
12
|
canvas_id: :id,
|
12
13
|
role_name: :role,
|
13
14
|
canvas_role_id: :role_id,
|
14
|
-
user_data: :user,
|
15
15
|
canvas_user_id: ->(r) { r['user']['id'] },
|
16
|
+
# NOTICE: The :account_id field is added by CanvasSync - it is not included in the Canvas API response
|
17
|
+
canvas_account_id: :account_id,
|
16
18
|
workflow_state: :workflow_state,
|
17
19
|
}, -> (api) {
|
18
|
-
admins = api.account_admins(
|
20
|
+
admins = api.account_admins(canvas_account_id).all_pages!
|
19
21
|
admin_data = admins.find{|admin| admin['id'] == canvas_id }
|
20
22
|
raise Footrest::HttpError::NotFound unless admin_data.present?
|
21
23
|
admin_data
|
22
24
|
})
|
23
|
-
|
24
|
-
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
25
|
-
|
26
25
|
end
|
@@ -10,12 +10,8 @@ class Role < ApplicationRecord
|
|
10
10
|
canvas_id: :id,
|
11
11
|
label: :label,
|
12
12
|
base_role_type: :base_role_type,
|
13
|
-
account: :account,
|
14
13
|
canvas_account_id: ->(r) { r.dig('account', 'id') },
|
15
14
|
permissions: :permissions,
|
16
15
|
workflow_state: :workflow_state,
|
17
16
|
}, -> (api) { api.get("/api/v1/accounts/#{canvas_account_id}/roles/#{canvas_id}") })
|
18
|
-
|
19
|
-
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
20
|
-
|
21
17
|
end
|
@@ -21,8 +21,6 @@ class Term < ApplicationRecord
|
|
21
21
|
term_data
|
22
22
|
})
|
23
23
|
|
24
|
-
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
25
|
-
|
26
24
|
# This is a sample scope created by the CanvasSync gem; feel
|
27
25
|
# free to customize it for your tool's requirements.
|
28
26
|
scope :active, -> {
|
data/lib/canvas_sync/job.rb
CHANGED
@@ -56,5 +56,15 @@ module CanvasSync
|
|
56
56
|
status: JobLog::ENQUEUED_STATUS,
|
57
57
|
)
|
58
58
|
end
|
59
|
+
|
60
|
+
def update_or_create_model(model, params)
|
61
|
+
if model.respond_to? :create_or_update
|
62
|
+
model.create_or_update(params)
|
63
|
+
elsif model.method_defined? :update_from_api_params!
|
64
|
+
model.find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params)
|
65
|
+
else
|
66
|
+
raise "Could not create/update #{model.name}. It must have a create_or_update(params) ClassMethod or implement ApiSyncable."
|
67
|
+
end
|
68
|
+
end
|
59
69
|
end
|
60
70
|
end
|
@@ -7,12 +7,16 @@ module CanvasSync
|
|
7
7
|
# @param job_chain [Hash]
|
8
8
|
# @param options [Hash]
|
9
9
|
def perform(job_chain, _options)
|
10
|
-
|
11
|
-
CanvasSync.get_canvas_sync_client(job_chain[:global_options])
|
12
|
-
|
13
|
-
|
10
|
+
updated_admin_ids = []
|
11
|
+
api_client = CanvasSync.get_canvas_sync_client(job_chain[:global_options])
|
12
|
+
CanvasSync.sync_scope(Account).find_each do |acc|
|
13
|
+
api_client.account_admins(acc.canvas_id).all_pages_each do |admin_params|
|
14
|
+
admin_params[:account_id] = acc.canvas_id
|
15
|
+
admin = update_or_create_model(Admin, admin_params)
|
16
|
+
updated_admin_ids.push(admin.id)
|
17
|
+
end
|
14
18
|
end
|
15
|
-
Admin.where.not(id:
|
19
|
+
Admin.where.not(id: updated_admin_ids).update_all(workflow_state: 'inactive')
|
16
20
|
CanvasSync.invoke_next(job_chain)
|
17
21
|
end
|
18
22
|
end
|
@@ -7,12 +7,15 @@ module CanvasSync
|
|
7
7
|
# @param job_chain [Hash]
|
8
8
|
# @param options [Hash]
|
9
9
|
def perform(job_chain, _options)
|
10
|
-
|
11
|
-
CanvasSync.get_canvas_sync_client(job_chain[:global_options])
|
12
|
-
|
13
|
-
|
10
|
+
updated_role_ids = []
|
11
|
+
api_client = CanvasSync.get_canvas_sync_client(job_chain[:global_options])
|
12
|
+
CanvasSync.sync_scope(Account).find_each do |acc|
|
13
|
+
api_client.list_roles(acc.canvas_id, state: %w[active inactive]).all_pages_each do |role_params|
|
14
|
+
role = update_or_create_model(Role, role_params)
|
15
|
+
updated_role_ids.push(role.id)
|
16
|
+
end
|
14
17
|
end
|
15
|
-
Role.where.not(id:
|
18
|
+
Role.where.not(id: updated_role_ids).update_all(workflow_state: 'inactive')
|
16
19
|
CanvasSync.invoke_next(job_chain)
|
17
20
|
end
|
18
21
|
end
|
@@ -10,9 +10,15 @@ module CanvasSync
|
|
10
10
|
def perform(job_chain, _options)
|
11
11
|
CanvasSync.get_canvas_sync_client(job_chain[:global_options]).terms("self").all_pages!.each do |term_params|
|
12
12
|
if job_chain[:global_options][:account_id]
|
13
|
-
|
13
|
+
# These branches are primarily to support Legacy apps
|
14
|
+
if Term.respond_to?(:create_or_update) && Term.method(:create_or_update).arity.abs == 2
|
15
|
+
Term.create_or_update(term_params, job_chain[:global_options][:account_id])
|
16
|
+
else
|
17
|
+
term_params[:account_id] |= job_chain[:global_options][:account_id]
|
18
|
+
update_or_create_model(Term, term_params)
|
19
|
+
end
|
14
20
|
else
|
15
|
-
Term
|
21
|
+
update_or_create_model(Term, term_params)
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
data/lib/canvas_sync/version.rb
CHANGED
@@ -2,10 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe CanvasSync::Jobs::SyncAdminsJob do
|
4
4
|
describe '#perform' do
|
5
|
+
let!(:account) { FactoryGirl.create(:account, canvas_id: 1) }
|
5
6
|
let(:admin_params) { open_canvas_fixture('admins') }
|
6
7
|
let(:job_chain) { { jobs: [], global_options: {}} }
|
7
8
|
|
8
|
-
it 'retrieves all
|
9
|
+
it 'retrieves all admins from the Canvas API and then invokes the next job' do
|
9
10
|
expect(CanvasSync).to receive(:invoke_next).with(job_chain)
|
10
11
|
|
11
12
|
expect {
|
@@ -2,10 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe CanvasSync::Jobs::SyncRolesJob do
|
4
4
|
describe '#perform' do
|
5
|
+
let!(:account) { FactoryGirl.create(:account, canvas_id: 1) }
|
5
6
|
let(:role_params) { open_canvas_fixture('roles') }
|
6
7
|
let(:job_chain) { { jobs: [], global_options: {}} }
|
7
8
|
|
8
|
-
it 'retrieves all
|
9
|
+
it 'retrieves all roles from the Canvas API and then invokes the next job' do
|
9
10
|
expect(CanvasSync).to receive(:invoke_next).with(job_chain)
|
10
11
|
|
11
12
|
expect {
|
@@ -8,19 +8,18 @@ RSpec.describe Admin, type: :model do
|
|
8
8
|
it { should validate_uniqueness_of(:canvas_id) }
|
9
9
|
end
|
10
10
|
|
11
|
-
describe '.
|
11
|
+
describe '.create_or_update_from_api_params' do
|
12
12
|
let(:admin_params) { open_canvas_fixture('admins')[0] }
|
13
13
|
|
14
14
|
context 'the admin does not already exist' do
|
15
15
|
it 'creates it' do
|
16
16
|
expect {
|
17
|
-
Admin.
|
17
|
+
Admin.create_or_update_from_api_params(admin_params)
|
18
18
|
}.to change { Admin.count }.by(1)
|
19
19
|
|
20
20
|
admin = Admin.last
|
21
21
|
expect(admin.role_name).to eq(admin_params['role'])
|
22
22
|
expect(admin.canvas_role_id).to eq(admin_params['role_id'])
|
23
|
-
expect(admin.user_data).to eq(admin_params['user'])
|
24
23
|
expect(admin.canvas_user_id).to eq(admin_params['user']['id'])
|
25
24
|
expect(admin.workflow_state).to eq(admin_params['workflow_state'])
|
26
25
|
end
|
@@ -31,13 +30,12 @@ RSpec.describe Admin, type: :model do
|
|
31
30
|
|
32
31
|
it 'updates it' do
|
33
32
|
expect {
|
34
|
-
Admin.
|
33
|
+
Admin.create_or_update_from_api_params(admin_params)
|
35
34
|
}.to_not change { Admin.count }
|
36
35
|
|
37
36
|
existing_admin.reload
|
38
37
|
expect(existing_admin.role_name).to eq(admin_params['role'])
|
39
38
|
expect(existing_admin.canvas_role_id).to eq(admin_params['role_id'])
|
40
|
-
expect(existing_admin.user_data).to eq(admin_params['user'])
|
41
39
|
expect(existing_admin.canvas_user_id).to eq(admin_params['user']['id'])
|
42
40
|
expect(existing_admin.workflow_state).to eq(admin_params['workflow_state'])
|
43
41
|
end
|
@@ -8,19 +8,19 @@ RSpec.describe Role, type: :model do
|
|
8
8
|
it { should validate_uniqueness_of(:canvas_id) }
|
9
9
|
end
|
10
10
|
|
11
|
-
describe '.
|
11
|
+
describe '.create_or_update_from_api_params' do
|
12
12
|
let(:role_params) { open_canvas_fixture('roles')[0] }
|
13
13
|
|
14
14
|
context 'the role does not already exist' do
|
15
15
|
it 'creates it' do
|
16
16
|
expect {
|
17
|
-
Role.
|
17
|
+
Role.create_or_update_from_api_params(role_params)
|
18
18
|
}.to change { Role.count }.by(1)
|
19
19
|
|
20
20
|
role = Role.last
|
21
21
|
expect(role.label).to eq(role_params['label'])
|
22
22
|
expect(role.base_role_type).to eq(role_params['base_role_type'])
|
23
|
-
expect(role.
|
23
|
+
expect(role.canvas_account_id).to eq(role_params['account']['id'])
|
24
24
|
expect(role.permissions).to eq(role_params['permissions'])
|
25
25
|
expect(role.workflow_state).to eq(role_params['workflow_state'])
|
26
26
|
end
|
@@ -31,13 +31,13 @@ RSpec.describe Role, type: :model do
|
|
31
31
|
|
32
32
|
it 'updates it' do
|
33
33
|
expect {
|
34
|
-
Role.
|
34
|
+
Role.create_or_update_from_api_params(role_params)
|
35
35
|
}.to_not change { Role.count }
|
36
36
|
|
37
37
|
existing_role.reload
|
38
38
|
expect(existing_role.label).to eq(role_params['label'])
|
39
39
|
expect(existing_role.base_role_type).to eq(role_params['base_role_type'])
|
40
|
-
expect(existing_role.
|
40
|
+
expect(existing_role.canvas_account_id).to eq(role_params['account']['id'])
|
41
41
|
expect(existing_role.permissions).to eq(role_params['permissions'])
|
42
42
|
expect(existing_role.workflow_state).to eq(role_params['workflow_state'])
|
43
43
|
end
|
@@ -29,13 +29,13 @@ RSpec.describe Term, type: :model do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
describe '.
|
32
|
+
describe '.create_or_update_from_api_params' do
|
33
33
|
let(:term_params) { open_canvas_fixture('terms')['enrollment_terms'][0] }
|
34
34
|
|
35
35
|
context 'the term does not already exist' do
|
36
36
|
it 'creates it' do
|
37
37
|
expect {
|
38
|
-
Term.
|
38
|
+
Term.create_or_update_from_api_params(term_params)
|
39
39
|
}.to change { Term.count }.by(1)
|
40
40
|
|
41
41
|
term = Term.last
|
@@ -54,7 +54,7 @@ RSpec.describe Term, type: :model do
|
|
54
54
|
|
55
55
|
it 'updates it' do
|
56
56
|
expect {
|
57
|
-
Term.
|
57
|
+
Term.create_or_update_from_api_params(term_params)
|
58
58
|
}.to_not change { Term.count }
|
59
59
|
|
60
60
|
existing_term.reload
|
@@ -10,6 +10,7 @@ class Admin < ApplicationRecord
|
|
10
10
|
include CanvasSync::ApiSyncable
|
11
11
|
|
12
12
|
validates :canvas_id, uniqueness: true, presence: true
|
13
|
+
belongs_to :account, primary_key: :canvas_id, foreign_key: :canvas_account_id, optional: true
|
13
14
|
belongs_to :user, primary_key: :canvas_id, foreign_key: :canvas_user_id, optional: true
|
14
15
|
belongs_to :role, primary_key: :canvas_id, foreign_key: :canvas_role_id, optional: true
|
15
16
|
|
@@ -17,16 +18,14 @@ class Admin < ApplicationRecord
|
|
17
18
|
canvas_id: :id,
|
18
19
|
role_name: :role,
|
19
20
|
canvas_role_id: :role_id,
|
20
|
-
user_data: :user,
|
21
21
|
canvas_user_id: ->(r) { r['user']['id'] },
|
22
|
+
# NOTICE: The :account_id field is added by CanvasSync - it is not included in the Canvas API response
|
23
|
+
canvas_account_id: :account_id,
|
22
24
|
workflow_state: :workflow_state,
|
23
25
|
}, -> (api) {
|
24
|
-
admins = api.account_admins(
|
26
|
+
admins = api.account_admins(canvas_account_id).all_pages!
|
25
27
|
admin_data = admins.find{|admin| admin['id'] == canvas_id }
|
26
28
|
raise Footrest::HttpError::NotFound unless admin_data.present?
|
27
29
|
admin_data
|
28
30
|
})
|
29
|
-
|
30
|
-
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
31
|
-
|
32
31
|
end
|
@@ -16,12 +16,8 @@ class Role < ApplicationRecord
|
|
16
16
|
canvas_id: :id,
|
17
17
|
label: :label,
|
18
18
|
base_role_type: :base_role_type,
|
19
|
-
account: :account,
|
20
19
|
canvas_account_id: ->(r) { r.dig('account', 'id') },
|
21
20
|
permissions: :permissions,
|
22
21
|
workflow_state: :workflow_state,
|
23
22
|
}, -> (api) { api.get("/api/v1/accounts/#{canvas_account_id}/roles/#{canvas_id}") })
|
24
|
-
|
25
|
-
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
26
|
-
|
27
23
|
end
|
@@ -27,8 +27,6 @@ class Term < ApplicationRecord
|
|
27
27
|
term_data
|
28
28
|
})
|
29
29
|
|
30
|
-
def self.create_or_update(params); find_or_initialize_by(canvas_id: params['id']).update_from_api_params!(params); end
|
31
|
-
|
32
30
|
# This is a sample scope created by the CanvasSync gem; feel
|
33
31
|
# free to customize it for your tool's requirements.
|
34
32
|
scope :active, -> {
|
data/spec/dummy/db/migrate/{20190702203628_create_roles.rb → 20190927204545_create_roles.rb}
RENAMED
@@ -10,11 +10,10 @@ class CreateRoles < ActiveRecord::Migration[5.1]
|
|
10
10
|
def change
|
11
11
|
create_table :roles do |t|
|
12
12
|
t.integer :canvas_id, null: false
|
13
|
-
t.string :label
|
14
|
-
t.string :base_role_type
|
15
|
-
t.json :account
|
13
|
+
t.string :label
|
14
|
+
t.string :base_role_type
|
16
15
|
t.integer :canvas_account_id
|
17
|
-
t.string :workflow_state
|
16
|
+
t.string :workflow_state
|
18
17
|
t.json :permissions
|
19
18
|
|
20
19
|
t.timestamps
|
data/spec/dummy/db/migrate/{20190702203629_create_admins.rb → 20190927204546_create_admins.rb}
RENAMED
@@ -11,13 +11,16 @@ class CreateAdmins < ActiveRecord::Migration[5.1]
|
|
11
11
|
create_table :admins do |t|
|
12
12
|
t.bigint :canvas_id, null: false
|
13
13
|
t.string :role_name
|
14
|
-
t.bigint :
|
15
|
-
t.
|
16
|
-
t.bigint :canvas_user_id
|
17
|
-
t.string :workflow_state
|
14
|
+
t.bigint :canvas_account_id
|
15
|
+
t.bigint :canvas_role_id
|
16
|
+
t.bigint :canvas_user_id
|
17
|
+
t.string :workflow_state
|
18
18
|
|
19
19
|
t.timestamps
|
20
20
|
end
|
21
21
|
add_index :admins, :canvas_id, unique: true
|
22
|
+
add_index :admins, :canvas_role_id
|
23
|
+
add_index :admins, :canvas_user_id
|
24
|
+
add_index :admins, :canvas_account_id
|
22
25
|
end
|
23
26
|
end
|