canvas_sync 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +178 -0
- data/Rakefile +23 -0
- data/lib/canvas_sync.rb +96 -0
- data/lib/canvas_sync/generators/install_generator.rb +54 -0
- data/lib/canvas_sync/generators/templates/course.rb +8 -0
- data/lib/canvas_sync/generators/templates/create_courses.rb +21 -0
- data/lib/canvas_sync/generators/templates/create_enrollments.rb +26 -0
- data/lib/canvas_sync/generators/templates/create_sections.rb +20 -0
- data/lib/canvas_sync/generators/templates/create_terms.rb +18 -0
- data/lib/canvas_sync/generators/templates/create_users.rb +18 -0
- data/lib/canvas_sync/generators/templates/enrollment.rb +8 -0
- data/lib/canvas_sync/generators/templates/section.rb +7 -0
- data/lib/canvas_sync/generators/templates/term.rb +28 -0
- data/lib/canvas_sync/generators/templates/user.rb +6 -0
- data/lib/canvas_sync/importers/bulk_importer.rb +54 -0
- data/lib/canvas_sync/jobs/application_job.rb +25 -0
- data/lib/canvas_sync/jobs/report_checker.rb +48 -0
- data/lib/canvas_sync/jobs/report_processor_job.rb +36 -0
- data/lib/canvas_sync/jobs/report_starter.rb +29 -0
- data/lib/canvas_sync/jobs/sync_provisioning_report_job.rb +58 -0
- data/lib/canvas_sync/jobs/sync_terms_job.rb +23 -0
- data/lib/canvas_sync/jobs/sync_users_job.rb +32 -0
- data/lib/canvas_sync/processors/provisioning_report_processor.rb +118 -0
- data/lib/canvas_sync/version.rb +3 -0
- data/spec/canvas_sync/canvas_sync_spec.rb +60 -0
- data/spec/canvas_sync/jobs/report_checker_spec.rb +62 -0
- data/spec/canvas_sync/jobs/report_processor_job_spec.rb +30 -0
- data/spec/canvas_sync/jobs/report_starter_spec.rb +27 -0
- data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +81 -0
- data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +18 -0
- data/spec/canvas_sync/jobs/sync_users_job_spec.rb +18 -0
- data/spec/canvas_sync/models/course_spec.rb +30 -0
- data/spec/canvas_sync/models/enrollment_spec.rb +30 -0
- data/spec/canvas_sync/models/section_spec.rb +24 -0
- data/spec/canvas_sync/models/term_spec.rb +71 -0
- data/spec/canvas_sync/models/user_spec.rb +18 -0
- data/spec/canvas_sync/processors/provisioning_report_processor_spec.rb +41 -0
- data/spec/dummy/README.rdoc +1 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/course.rb +14 -0
- data/spec/dummy/app/models/enrollment.rb +14 -0
- data/spec/dummy/app/models/section.rb +13 -0
- data/spec/dummy/app/models/term.rb +34 -0
- data/spec/dummy/app/models/user.rb +12 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20170831220702_create_courses.rb +27 -0
- data/spec/dummy/db/migrate/20170831221129_create_users.rb +24 -0
- data/spec/dummy/db/migrate/20170905192509_create_enrollments.rb +32 -0
- data/spec/dummy/db/migrate/20170906193506_create_terms.rb +24 -0
- data/spec/dummy/db/migrate/20170906203438_create_sections.rb +26 -0
- data/spec/dummy/db/schema.rb +88 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +828 -0
- data/spec/dummy/log/test.log +14582 -0
- data/spec/factories/course_factory.rb +10 -0
- data/spec/factories/enrollment_factory.rb +5 -0
- data/spec/factories/section_factory.rb +5 -0
- data/spec/factories/term_factory.rb +10 -0
- data/spec/factories/user_factory.rb +9 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/fake_canvas.rb +22 -0
- data/spec/support/fixtures/canvas_responses/terms.json +64 -0
- data/spec/support/fixtures/reports/courses.csv +3 -0
- data/spec/support/fixtures/reports/enrollments.csv +3 -0
- data/spec/support/fixtures/reports/provisioning_csv +0 -0
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +3 -0
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +4 -0
- data/spec/support/fixtures/reports/sections.csv +3 -0
- data/spec/support/fixtures/reports/users.csv +4 -0
- metadata +423 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe User, type: :model do
|
4
|
+
let(:subject) { FactoryGirl.create(:user) }
|
5
|
+
|
6
|
+
describe 'validations' do
|
7
|
+
it { should validate_presence_of(:canvas_user_id) }
|
8
|
+
it { should validate_uniqueness_of(:canvas_user_id) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'associations' do
|
12
|
+
it do
|
13
|
+
should have_many(:enrollments)
|
14
|
+
.with_primary_key(:canvas_user_id)
|
15
|
+
.with_foreign_key(:canvas_user_id)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe CanvasSync::Processors::ProvisioningReportProcessor do
|
4
|
+
let(:subject) { CanvasSync::Processors::ProvisioningReportProcessor }
|
5
|
+
|
6
|
+
describe '#process' do
|
7
|
+
it 'process users' do
|
8
|
+
expect {
|
9
|
+
subject.process('spec/support/fixtures/reports/users.csv', { models: ['users'] })
|
10
|
+
}.to change { User.count }.by(2)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'processes courses' do
|
14
|
+
expect {
|
15
|
+
subject.process('spec/support/fixtures/reports/courses.csv', { models: ['courses'] })
|
16
|
+
}.to change { Course.count }.by(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'processes enrollments' do
|
20
|
+
expect {
|
21
|
+
subject.process('spec/support/fixtures/reports/enrollments.csv', { models: ['enrollments'] })
|
22
|
+
}.to change { Enrollment.count }.by(2)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'processes sections' do
|
26
|
+
expect {
|
27
|
+
subject.process('spec/support/fixtures/reports/sections.csv', { models: ['sections'] })
|
28
|
+
}.to change { Section.count }.by(2)
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'options[:models] is multiple models' do
|
32
|
+
it 'extracts the ZIP and processes each model' do
|
33
|
+
user_count = User.count
|
34
|
+
course_count = Course.count
|
35
|
+
subject.process('spec/support/fixtures/reports/provisioning_csv', { models: ['courses', 'users'] })
|
36
|
+
expect(User.count).to eq(user_count + 2)
|
37
|
+
expect(Course.count).to eq(course_count + 2)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dummy Rails App for gem testing
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class Course < ApplicationRecord
|
10
|
+
validates :canvas_course_id, uniqueness: true, presence: true
|
11
|
+
belongs_to :term, foreign_key: :canvas_term_id, primary_key: :canvas_term_id, optional: true
|
12
|
+
has_many :enrollments, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
|
13
|
+
has_many :sections, primary_key: :canvas_course_id, foreign_key: :canvas_course_id
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class Enrollment < ApplicationRecord
|
10
|
+
validates :canvas_enrollment_id, uniqueness: true, presence: true
|
11
|
+
belongs_to :user, primary_key: :canvas_user_id, foreign_key: :canvas_user_id, optional: true
|
12
|
+
belongs_to :course, primary_key: :canvas_course_id, foreign_key: :canvas_course_id, optional: true
|
13
|
+
belongs_to :section, primary_key: :canvas_section_id, foreign_key: :canvas_section_id, optional: true
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class Section < ApplicationRecord
|
10
|
+
validates :canvas_section_id, uniqueness: true, presence: true
|
11
|
+
belongs_to :course, primary_key: :canvas_course_id, foreign_key: :canvas_course_id, optional: true
|
12
|
+
has_many :enrollments, primary_key: :canvas_section_id, foreign_key: :canvas_section_id
|
13
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class Term < ApplicationRecord
|
10
|
+
validates :canvas_term_id, uniqueness: true, presence: true
|
11
|
+
has_many :courses, foreign_key: :canvas_term_id, primary_key: :canvas_term_id
|
12
|
+
|
13
|
+
# This is a sample scope created by the CanvasSync gem; feel
|
14
|
+
# free to customize it for your tool's requirements.
|
15
|
+
scope :active, -> {
|
16
|
+
where(workflow_state: 'active')
|
17
|
+
.where("start_at <= ? OR start_at IS NULL", 15.days.from_now)
|
18
|
+
.where("end_at >= ? OR end_at IS NULL", 15.days.ago)
|
19
|
+
}
|
20
|
+
|
21
|
+
def self.create_or_update(term_params)
|
22
|
+
term = Term.find_or_initialize_by(canvas_term_id: term_params['id'])
|
23
|
+
|
24
|
+
term.assign_attributes(name: term_params['name'],
|
25
|
+
start_at: term_params['start_at'],
|
26
|
+
end_at: term_params['end_at'],
|
27
|
+
workflow_state: term_params['workflow_state'],
|
28
|
+
grading_period_group_id: term_params['grading_period_group_id'],
|
29
|
+
sis_id: term_params['sis_term_id'])
|
30
|
+
|
31
|
+
term.save! if term.changed?
|
32
|
+
term
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MODEL
|
3
|
+
# This model was auto generated by the CanvasSync Gem.
|
4
|
+
# You can customize it as needed, but make sure you test
|
5
|
+
# any changes you make to the auto generated methods.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class User < ApplicationRecord
|
10
|
+
validates :canvas_user_id, uniqueness: true, presence: true
|
11
|
+
has_many :enrollments, primary_key: :canvas_user_id, foreign_key: :canvas_user_id
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require 'rails/all'
|
4
|
+
|
5
|
+
Bundler.require(*Rails.groups)
|
6
|
+
require "canvas_sync"
|
7
|
+
|
8
|
+
module Dummy
|
9
|
+
class Application < Rails::Application
|
10
|
+
# Settings in config/environments/* take precedence over those specified here.
|
11
|
+
# Application configuration should go into files in config/initializers
|
12
|
+
# -- all .rb files in that directory are automatically loaded.
|
13
|
+
|
14
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
15
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
16
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
17
|
+
|
18
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
19
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
20
|
+
# config.i18n.default_locale = :de
|
21
|
+
|
22
|
+
# Do not swallow errors in after_commit/after_rollback callbacks.
|
23
|
+
# config.active_record.raise_in_transactional_callbacks = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# SQLite version 3.x
|
2
|
+
# gem install sqlite3
|
3
|
+
#
|
4
|
+
# Ensure the SQLite 3 gem is defined in your Gemfile
|
5
|
+
# gem 'sqlite3'
|
6
|
+
#
|
7
|
+
default: &default
|
8
|
+
adapter: sqlite3
|
9
|
+
pool: 5
|
10
|
+
timeout: 5000
|
11
|
+
|
12
|
+
development:
|
13
|
+
<<: *default
|
14
|
+
database: db/development.sqlite3
|
15
|
+
|
16
|
+
# Warning: The database defined as "test" will be erased and
|
17
|
+
# re-generated from your development database when you run "rake".
|
18
|
+
# Do not set this db to the same as development or production.
|
19
|
+
test:
|
20
|
+
<<: *default
|
21
|
+
database: db/test.sqlite3
|
22
|
+
|
23
|
+
production:
|
24
|
+
<<: *default
|
25
|
+
database: db/production.sqlite3
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Rails.application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb.
|
3
|
+
|
4
|
+
# In the development environment your application's code is reloaded on
|
5
|
+
# every request. This slows down response time but is perfect for development
|
6
|
+
# since you don't have to restart the web server when you make code changes.
|
7
|
+
config.cache_classes = false
|
8
|
+
|
9
|
+
# Do not eager load code on boot.
|
10
|
+
config.eager_load = false
|
11
|
+
|
12
|
+
# Show full error reports and disable caching.
|
13
|
+
config.consider_all_requests_local = true
|
14
|
+
config.action_controller.perform_caching = false
|
15
|
+
|
16
|
+
# Don't care if the mailer can't send.
|
17
|
+
config.action_mailer.raise_delivery_errors = false
|
18
|
+
|
19
|
+
# Print deprecation notices to the Rails logger.
|
20
|
+
config.active_support.deprecation = :log
|
21
|
+
|
22
|
+
# Raise an error on page load if there are pending migrations.
|
23
|
+
config.active_record.migration_error = :page_load
|
24
|
+
|
25
|
+
# Debug mode disables concatenation and preprocessing of assets.
|
26
|
+
# This option may cause significant delays in view rendering with a large
|
27
|
+
# number of complex assets.
|
28
|
+
config.assets.debug = true
|
29
|
+
|
30
|
+
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
|
31
|
+
# yet still be able to expire them through the digest params.
|
32
|
+
config.assets.digest = true
|
33
|
+
|
34
|
+
# Adds additional error checking when serving assets at runtime.
|
35
|
+
# Checks for improperly declared sprockets dependencies.
|
36
|
+
# Raises helpful error messages.
|
37
|
+
config.assets.raise_runtime_errors = true
|
38
|
+
|
39
|
+
# Raises error for missing translations
|
40
|
+
# config.action_view.raise_on_missing_translations = true
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Rails.application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb.
|
3
|
+
|
4
|
+
# The test environment is used exclusively to run your application's
|
5
|
+
# test suite. You never need to work with it otherwise. Remember that
|
6
|
+
# your test database is "scratch space" for the test suite and is wiped
|
7
|
+
# and recreated between test runs. Don't rely on the data there!
|
8
|
+
config.cache_classes = true
|
9
|
+
|
10
|
+
# Do not eager load code on boot. This avoids loading your whole application
|
11
|
+
# just for the purpose of running a single test. If you are using a tool that
|
12
|
+
# preloads Rails for running tests, you may have to set it to true.
|
13
|
+
config.eager_load = false
|
14
|
+
|
15
|
+
# Configure static file server for tests with Cache-Control for performance.
|
16
|
+
config.serve_static_files = true
|
17
|
+
config.static_cache_control = 'public, max-age=3600'
|
18
|
+
|
19
|
+
# Show full error reports and disable caching.
|
20
|
+
config.consider_all_requests_local = true
|
21
|
+
config.action_controller.perform_caching = false
|
22
|
+
|
23
|
+
# Raise exceptions instead of rendering exception templates.
|
24
|
+
config.action_dispatch.show_exceptions = false
|
25
|
+
|
26
|
+
# Disable request forgery protection in test environment.
|
27
|
+
config.action_controller.allow_forgery_protection = false
|
28
|
+
|
29
|
+
# Tell Action Mailer not to deliver emails to the real world.
|
30
|
+
# The :test delivery method accumulates sent emails in the
|
31
|
+
# ActionMailer::Base.deliveries array.
|
32
|
+
config.action_mailer.delivery_method = :test
|
33
|
+
|
34
|
+
# Randomize the order test cases are executed.
|
35
|
+
config.active_support.test_order = :random
|
36
|
+
|
37
|
+
# Print deprecation notices to the stderr.
|
38
|
+
config.active_support.deprecation = :stderr
|
39
|
+
|
40
|
+
# Raises error for missing translations
|
41
|
+
# config.action_view.raise_on_missing_translations = true
|
42
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Version of your assets, change this if you want to expire all your assets.
|
4
|
+
Rails.application.config.assets.version = '1.0'
|
5
|
+
|
6
|
+
# Add additional assets to the asset load path
|
7
|
+
# Rails.application.config.assets.paths << Emoji.images_path
|
8
|
+
|
9
|
+
# Precompile additional assets.
|
10
|
+
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
|
11
|
+
# Rails.application.config.assets.precompile += %w( search.js )
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
|
9
|
+
end
|
10
|
+
|
11
|
+
# To enable root element in JSON for ActiveRecord objects.
|
12
|
+
# ActiveSupport.on_load(:active_record) do
|
13
|
+
# self.include_root_in_json = true
|
14
|
+
# end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Your secret key is used for verifying the integrity of signed cookies.
|
4
|
+
# If you change this key, all old signed cookies will become invalid!
|
5
|
+
|
6
|
+
# Make sure the secret is at least 30 characters and all random,
|
7
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
8
|
+
# You can use `rake secret` to generate a secure secret key.
|
9
|
+
|
10
|
+
# Make sure the secrets in this file are kept private
|
11
|
+
# if you're sharing your code publicly.
|
12
|
+
|
13
|
+
development:
|
14
|
+
secret_key_base: 4fc03e27b5bfc390d7beaf99e739c1a9ad4264d58cd2a1db40fbb83b6ed320e1fa77fb4e0dd7c24816811170a59d65b623bc887b4ca1e0bd0c57348e9e304f73
|
15
|
+
|
16
|
+
test:
|
17
|
+
secret_key_base: 7700238de042256ef63c58a57c6bf431b6ebca79f95f66ccd04b5ad8b89761db15a9b89a85b08ace8a69ae3867462cb9514eb21d0e591d8f3881de79d7b72675
|
18
|
+
|
19
|
+
# Do not keep production secrets in the repository,
|
20
|
+
# instead read values from the environment.
|
21
|
+
production:
|
22
|
+
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MIGRATION
|
3
|
+
# This migration was auto generated by the CanvasSync Gem.
|
4
|
+
# You can add new columns to this table, but removing or
|
5
|
+
# re-naming ones created here may break Canvas Syncing.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class CreateCourses < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :courses do |t|
|
12
|
+
t.bigint :canvas_course_id, null: false
|
13
|
+
t.string :sis_id
|
14
|
+
t.string :short_name
|
15
|
+
t.string :long_name
|
16
|
+
t.integer :canvas_account_id
|
17
|
+
t.integer :canvas_term_id
|
18
|
+
t.integer :term_sis_id
|
19
|
+
t.datetime :start_date
|
20
|
+
t.datetime :end_date
|
21
|
+
|
22
|
+
t.timestamps
|
23
|
+
end
|
24
|
+
|
25
|
+
add_index :courses, :canvas_course_id, unique: true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# AUTO GENERATED MIGRATION
|
3
|
+
# This migration was auto generated by the CanvasSync Gem.
|
4
|
+
# You can add new columns to this table, but removing or
|
5
|
+
# re-naming ones created here may break Canvas Syncing.
|
6
|
+
#
|
7
|
+
|
8
|
+
|
9
|
+
class CreateUsers < ActiveRecord::Migration[5.1]
|
10
|
+
def change
|
11
|
+
create_table :users do |t|
|
12
|
+
t.bigint :canvas_user_id, null: false
|
13
|
+
t.string :sis_id
|
14
|
+
t.string :email
|
15
|
+
t.string :first_name
|
16
|
+
t.string :last_name
|
17
|
+
t.string :status
|
18
|
+
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
|
22
|
+
add_index :users, :canvas_user_id, unique: true
|
23
|
+
end
|
24
|
+
end
|