gaku_core 0.3.0.pre.0 → 0.3.0.pre.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/gaku/courses.js.coffee +20 -0
  3. data/app/assets/javascripts/gaku/exams.js.coffee +23 -0
  4. data/app/assets/stylesheets/gaku/bootstrap_and_theme.css.scss +574 -0
  5. data/app/controllers/gaku/courses/exams/exam_portion_scores_controller.rb +23 -0
  6. data/app/controllers/gaku/courses/exams_controller.rb +291 -0
  7. data/app/controllers/gaku/exams_controller.rb +170 -0
  8. data/app/helpers/gaku/gaku_helper.rb +155 -0
  9. data/app/models/gaku/enrollment.rb +1 -1
  10. data/app/models/gaku/exam_portion.rb +9 -0
  11. data/app/models/gaku/semester_connector.rb +1 -1
  12. data/app/models/gaku/student.rb +4 -0
  13. data/app/views/gaku/admin/grading_methods/_form_fields.html.slim +7 -0
  14. data/app/views/gaku/courses/_form_fields.html.slim +5 -0
  15. data/app/views/gaku/courses/exams/exam_portion_scores/update.js.erb +5 -0
  16. data/app/views/gaku/courses/exams/grading/_calculations.html.slim +16 -0
  17. data/app/views/gaku/courses/exams/grading/_exam_portion_score_form.htmls.lim +0 -0
  18. data/app/views/gaku/courses/exams/grading/_exam_scores.html.slim +78 -0
  19. data/app/views/gaku/courses/exams/grading/_students.html.slim +12 -0
  20. data/app/views/gaku/courses/exams/grading.html.slim +38 -0
  21. data/app/views/gaku/layouts/gaku.html.slim +25 -0
  22. data/app/views/gaku/shared/menu/_global.html.erb +1 -1
  23. data/config/locales/bg.yml +421 -413
  24. data/config/locales/en.yml +53 -110
  25. data/config/locales/ja.yml +891 -883
  26. data/config/locales/pt-BR.yml +11 -3
  27. data/config/locales/zh-CN.yml +9 -1
  28. data/config/routes.rb +120 -5
  29. data/db/migrate/20160209100945_add_score_types_to_exam_portions.rb +6 -0
  30. data/db/migrate/20160209104713_add_fields_to_exam_portion_score.rb +6 -0
  31. data/lib/gaku/grading/single/percentage.rb +3 -3
  32. data/lib/gaku/grading/single/score.rb +3 -3
  33. data/lib/gaku/testing/factories/exam_portion_factory.rb +1 -1
  34. metadata +20 -2
@@ -0,0 +1,291 @@
1
+ module Gaku
2
+ class Courses::ExamsController < GakuController
3
+
4
+ respond_to :html
5
+
6
+
7
+ def grading
8
+
9
+ def init_variables
10
+ @course = Course.find(params[:course_id])
11
+ @exam = Exam.find(params[:id])
12
+ @students = @course.students
13
+ if params[:id] != nil
14
+ @exams = Exam.find_all_by_id(params[:id])
15
+ else
16
+ @exams = @course.syllabus.exams.all
17
+ end
18
+
19
+ # 試験の平均点を入れるハッシュ
20
+ @exams_average = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)}
21
+
22
+ # 試験の合計点を入れるハッシュ
23
+ @student_exams_total_score = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)}
24
+
25
+ # 偏差値を入れるハッシュ
26
+ @student_exams_deviation = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)}
27
+
28
+ # for grade and rank--------
29
+ # 10段階用の設定
30
+ # @student_exams_grade: 生徒の10段階を入れるHash。
31
+ @student_exams_grade = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)}
32
+
33
+ # 5段階用の設定
34
+ # @student_exams_rank: 生徒の5段階を入れるHash。
35
+ @student_exams_rank = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)}
36
+ end
37
+
38
+ def set_student_exams_total_scores_and_set_exams_average
39
+ @exams.each do |exam|
40
+ @students.each do |student|
41
+
42
+ # 素点用と得点用変数の初期化 --------
43
+ @student_exams_total_score[:raw][exam.id][student.id] = 0.0
44
+ @student_exams_total_score[exam.id][student.id] = 0.0
45
+
46
+ @exams_average[:raw][exam.id] = 0.0
47
+ @exams_average[exam.id] = 0.0
48
+
49
+ exam.exam_portions.each do |portion|
50
+ seps = student.exam_portion_scores.where(exam_portion_id: portion.id).first.score.to_f
51
+
52
+ @student_exams_total_score[:raw][exam.id][student.id] += seps
53
+ if exam.use_weighting
54
+ @student_exams_total_score[exam.id][student.id] += (portion.weight.to_f / 100) * seps
55
+ else
56
+ @student_exams_total_score[exam.id][student.id] += seps
57
+ end
58
+ end
59
+
60
+ # calc for average --------
61
+ @exams_average[:raw][exam.id] += @student_exams_total_score[:raw][exam.id][student.id]
62
+ @exams_average[exam.id] += @student_exams_total_score[exam.id][student.id]
63
+ end
64
+
65
+ # set Exams Average --------
66
+ if exam === @exams.last
67
+ @exams_average[:raw][exam.id] = fix_digit @exams_average[:raw][exam.id] / @students.length, 4
68
+ @exams_average[exam.id] = fix_digit @exams_average[exam.id] / @students.length, 4
69
+ end
70
+ end
71
+ end
72
+
73
+ def set_student_exams_deviaton
74
+
75
+ def get_standard_deviation exam
76
+ scratch_standard_deviation = 0.0
77
+ @students.each do |student|
78
+ scratch_standard_deviation += (@student_exams_total_score[exam.id][student.id] - @exams_average[exam.id]) ** 2
79
+ end
80
+ return Math.sqrt scratch_standard_deviation / @students.length
81
+ end
82
+
83
+ def get_deviation standard_deviation, exam, student
84
+ scratch_deviation = (@student_exams_total_score[exam.id][student.id] - @exams_average[exam.id]) / standard_deviation
85
+ if scratch_deviation.nan?
86
+ return 50
87
+ else
88
+ return fix_digit @student_exams_deviation[exam.id][student.id] * 10 + 50, 4
89
+ end
90
+ end
91
+
92
+ # start main --------
93
+ @exams.each do |exam|
94
+ standard_deviation = get_standard_deviation(exam)
95
+
96
+ # set deviations --------
97
+ @students.each do |student|
98
+ @student_exams_deviation[exam.id][student.id] = get_deviation(standard_deviation, exam, student)
99
+ end
100
+ end
101
+ end
102
+
103
+ def set_student_exams_grade_and_rank
104
+
105
+ # def method_ratio(grading_method)
106
+ def method_ratio
107
+ default_grade_level_deviation = [100, 66, 62, 58, 55, 50, 45, 37, 0]
108
+ @rank_level = [15, 20]
109
+
110
+ # default_grade_level_percent = [5, 5, 10, 10, 30, 10, 100]
111
+
112
+ default = {
113
+ # for grade ----
114
+ g10: 100,
115
+ g9: 66,
116
+ g8: 62,
117
+
118
+ # for rank----
119
+ r10: 5,
120
+ r9: 5,
121
+ r8: 10
122
+ }
123
+
124
+ default = {
125
+ grade:{
126
+ g10: 100,
127
+ g9: 66,
128
+ g8: 62
129
+ },
130
+ rank: {
131
+ r10: 5,
132
+ r9: 5,
133
+ r8: 10
134
+ }
135
+ }
136
+
137
+ # @grade_level_deviation:
138
+ # 10段階の全体評価で判定する時に使う変数。
139
+ # 決められた偏差値を基に、生徒の偏差値と比べ、その多寡で評価を行う。
140
+ # @grade_level_percent:
141
+ # 10段階の相対評価で判定する時に使う変数。
142
+ # 決められたパーセンテージを元に、生徒がクラス内で上位何%以内かを調べ、評価を行う。
143
+
144
+ @ = JSON.parse grading_method.method.arguments, symbolize_names: true
145
+
146
+ @grade_level_deviation = [100, 66, 62, 58, 55, 50, 45, 37, 0]
147
+ @grade_level_percent = [5, 5, 10, 10, 30, 10, 100]
148
+
149
+ # @rank_level: 5段階を付ける時に使うパーセンテージ配列の変数。
150
+ @rank_level = [15, 20]
151
+
152
+
153
+
154
+ # Grade and Rank Calculation (ここは別途光ヶ丘の生徒評価表を参照して下さい)-------- {
155
+ # set grade and rank --------
156
+ @exams.each do |exam|
157
+
158
+ # 生徒の順位用配列を作成
159
+ exam_student_scores = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)} # 生徒の順位を出す為の変数。
160
+
161
+ # 試験毎の合計点数と生徒IDをexam_student_scoresに格納する。
162
+ @students.each do |student|
163
+ exam_student_scores[student.id] = @student_exams_total_score[exam.id][student.id]
164
+ end
165
+ # 試験のスコアを降順に並び替える
166
+ exam_student_scores = exam_student_scores.sort_by {|key,val| -val}
167
+
168
+ # 採点方式を選択、その採点方式でGradeを決定。
169
+ grading_method = 1
170
+ grade_point = 10
171
+
172
+ case grading_method
173
+
174
+ # calc for 全体評価
175
+ when 1
176
+ @grade_level_deviation.each_with_index do |glevel, i|
177
+ @students.each do |student|
178
+ if @grade_level_deviation[i] > @student_exams_deviation[exam.id][student.id] && @grade_level_deviation[i+1] <= @student_exams_deviation[exam.id][student.id]
179
+ @student_exams_grade[exam.id][student.id] = grade_point
180
+ end
181
+ end
182
+ grade_point -= 1
183
+ end
184
+
185
+ # calc for 相対評価
186
+ when 2
187
+ scratch_exam_student_scores = exam_student_scores.clone
188
+ grade_limit_nums = []
189
+ @grade_level_percent.each do |glevel|
190
+ grade_limit_nums.push((@students.length * (glevel.to_f / 100)).ceil)
191
+ end
192
+ grade_limit_nums.each do |gnum|
193
+ i = 0
194
+ while i < gnum && scratch_exam_student_scores.length != 0
195
+ @student_exams_grade[exam.id][scratch_exam_student_scores.shift[0]] = grade_point
196
+ i += 1
197
+ end
198
+ grade_point -= 1
199
+ end
200
+
201
+ end
202
+
203
+ # Rank Calculation --------
204
+ # rankPoint = 5
205
+ # @students.each do |student|
206
+ # @student_exams_rank[exam.id][student.id] = 3
207
+ # end
208
+ # rankNums = []
209
+ # @rank_level.each do |rlevel|
210
+ # rankNums.push((@students.length * (rlevel.to_f / 100)).ceil)
211
+ # end
212
+ # rankNums.each do |rnum|
213
+ # i = 0
214
+ # while i < rnum && exam_student_scores.length != 0
215
+ # scoreMem = exam_student_scores.shift()
216
+ # @student_exams_rank[exam.id][scoreMem[1]] = rankPoint
217
+ # if exam_student_scores.length != 0 and scoreMem[0] == exam_student_scores[0][0]
218
+ # rnum += 1
219
+ # end
220
+ # i += 1
221
+ # end
222
+ # rankPoint -= 1
223
+ # end
224
+ # exam_student_scores.each do |score|
225
+ # if @student_exams_grade[exam.id][socre[1]] == 3
226
+ # @student_exams_rank[exam.id][score[1]] = 2
227
+ # elsif @student_exams_grade[exam.id][socre[1]] < 3
228
+ # @student_exams_rank[exam.id][score[1]] = 1
229
+ # end
230
+ # end
231
+ end
232
+ end
233
+
234
+ # start main --------
235
+ # p '@exam.grading_method.method -------'
236
+ # p @exam.grading_method
237
+
238
+ # case @exam.grading_method.method
239
+ case "ratio"
240
+
241
+ when "ratio"
242
+ # method_ratio(@exam.grading_method)
243
+ # method_ratio()
244
+ method = Grading::Ratio.new (arguments)
245
+
246
+ exam.student_score.each do |student|
247
+ results << method.grade (student, exam)
248
+ end
249
+
250
+ return results
251
+
252
+
253
+ end
254
+
255
+ end
256
+
257
+ def fix_digit num, digit_num
258
+ for_fix = 10 ** digit_num
259
+ num = num * for_fix
260
+ if num.nan?
261
+ num = 0
262
+ else
263
+ num = num.truncate.to_f / for_fix.to_f
264
+ end
265
+ return num
266
+ end
267
+
268
+ # start main --------
269
+ init_variables()
270
+ init_portion_scores()
271
+ set_student_exams_total_scores_and_set_exams_average()
272
+ set_student_exams_deviaton()
273
+ set_student_exams_grade_and_rank()
274
+
275
+ respond_with @exam
276
+ end
277
+
278
+ private
279
+
280
+ def init_portion_scores
281
+ @students.each do |student|
282
+ @exam.exam_portions.each do |portion|
283
+ unless portion.exam_portion_scores.pluck(:student_id).include?(student.id)
284
+ ExamPortionScore.create!(exam_portion: portion, student: student)
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ end
291
+ end
@@ -0,0 +1,170 @@
1
+ module Gaku
2
+ class ExamsController < GakuController
3
+
4
+ respond_to :html, :js, :json
5
+ respond_to :xls, only: :export
6
+
7
+ include Gaku::Grading::Calculations
8
+
9
+ before_action :set_exam, only: %i( show edit update soft_delete )
10
+ before_action :set_unscoped_exam, only: %i( destroy recovery )
11
+ before_action :load_data, only: %i( new edit )
12
+
13
+ def index
14
+ if params[:course_id]
15
+ @exams = Course.find(params[:course_id]).syllabus.exams
16
+ else
17
+ @exams = Exam.all
18
+ @exam = Exam.new
19
+ end
20
+
21
+ @exam.exam_portions.build
22
+ set_count
23
+ respond_to do |format|
24
+ format.html
25
+ format.json { render json: @exams.as_json(include: {exam_portions: {include: :exam_portion_scores}})}
26
+ end
27
+ end
28
+
29
+ def show
30
+ respond_with @exam
31
+ end
32
+
33
+ def new
34
+ @exam = Exam.new
35
+ @master_portion = @exam.exam_portions.new
36
+ respond_with @exam
37
+ end
38
+
39
+ def create
40
+ @exam = Exam.create(exam_params)
41
+ @exam.save
42
+ set_count
43
+ respond_with @exam
44
+ end
45
+
46
+ def edit
47
+ respond_with @exam
48
+ end
49
+
50
+ def update
51
+ @exam.update(exam_params)
52
+ respond_with @exam, location: [:edit, @exam]
53
+ end
54
+
55
+ def destroy
56
+ @exam.destroy
57
+ set_count
58
+ respond_with @exam
59
+ end
60
+
61
+ def recovery
62
+ @exam.recover
63
+ respond_with @exam
64
+ end
65
+
66
+ def soft_delete
67
+ @exam.soft_delete
68
+ respond_with @exam, location: exams_path
69
+ end
70
+
71
+ def export
72
+ @course = Course.find(params[:course_id])
73
+ end
74
+
75
+
76
+ # def grading
77
+ # @course = Course.find(params[:course_id])
78
+ # @exam = Exam.find(params[:id])
79
+ # @students = @course.students
80
+
81
+ # respond_with @exam
82
+ # find_exams
83
+
84
+ # calculate_totals
85
+ # calculate_exam_averages
86
+ # calculate_deviation
87
+ # calculate_rank_and_grade
88
+
89
+ # @path_to_exam = course_path(id: params[:course_id])
90
+
91
+ # #exam_portions need reload to properly include exam_portion_score in as_json
92
+ # @exams.each { |exam| exam.exam_portions.reload }
93
+
94
+ # respond_to do |format|
95
+ # format.json do render json: {
96
+ # student_total_scores: @student_total_scores.as_json,
97
+ # exams: @exams.as_json(include: {exam_portions: {include: :exam_portion_scores }},root: false),
98
+ # course: @course.as_json(root: false),
99
+ # exam_averages: @exam_averages.as_json(root: false),
100
+ # deviation: @deviation.as_json(root: false),
101
+ # students: @students.to_json(root: false),
102
+ # grades: @grades.as_json(root: false),
103
+ # ranks: @ranks.as_json(root: false),
104
+ # attendances: @student_portion_attendance.as_json(root: true, include: :attendance_type),
105
+ # path_to_exam: @path_to_exam.to_json,
106
+ # completion: @completion
107
+ # }end
108
+ # format.html { render 'gaku/exams/grading' }
109
+ # end
110
+ # end
111
+
112
+ def completed
113
+ @exam = Exam.find(params[:id])
114
+ @course = Course.find(params[:course_id])
115
+ @students = @course.students
116
+
117
+
118
+ respond_with @exam.completed_by_students(@students)
119
+ end
120
+
121
+ protected
122
+
123
+ def exam_params
124
+ params.require(:exam).permit(attributes)
125
+ end
126
+
127
+ private
128
+
129
+ def load_data
130
+ @departments = Department.all
131
+ end
132
+
133
+ def t_resource
134
+ t(:'exam.singular')
135
+ end
136
+
137
+ def attributes
138
+ [:name, :department_id, :weight, :description, :adjustments, :use_weighting,
139
+ exam_portions_attributes: [:id, :name, :weight, :problem_count, :max_score, :description, :adjustments]
140
+ ]
141
+ end
142
+
143
+ def set_exam
144
+ @exam = Exam.find(params[:id])
145
+ set_notable
146
+ end
147
+
148
+ def set_unscoped_exam
149
+ @exam = Exam.unscoped.find(params[:id])
150
+ set_notable
151
+ end
152
+
153
+ def set_notable
154
+ @notable = @exam
155
+ @notable_resource = @notable.class.to_s.underscore.split('/')[1].gsub('_','-')
156
+ end
157
+
158
+ def set_count
159
+ @count = Exam.count
160
+ end
161
+
162
+ def find_exams
163
+ if params[:id] != nil
164
+ @exams = Exam.where(id: params[:id])
165
+ else
166
+ @exams = @course.syllabus.exams
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,155 @@
1
+ module Gaku
2
+ module GakuHelper
3
+
4
+ include SortHelper
5
+ include TranslationsHelper
6
+ include FlashHelper
7
+
8
+ def broadcast(channel, &block)
9
+ message = {:channel => channel, :data => capture(&block)}
10
+ uri = URI.parse("http://localhost:9292/faye")
11
+ Net::HTTP.post_form(uri, :message => message.to_json)
12
+ end
13
+
14
+
15
+ def tr_for(resource, &block)
16
+ content_tag :tr, id: "#{resource.class.to_s.demodulize.underscore.dasherize}-#{resource.id}" do
17
+ block.call
18
+ end
19
+ end
20
+
21
+ def current_parent_controller
22
+ controller.controller_path.split('/').second
23
+ end
24
+
25
+ def current_controller_action
26
+ controller.action_name
27
+ end
28
+
29
+ def drag_field
30
+ content_tag :td, class: 'sort-handler' do
31
+ content_tag :i, nil, class: 'icon-move'
32
+ end
33
+ end
34
+
35
+ def can_edit?
36
+ if controller.action_name.include?('edit')
37
+ true
38
+ else
39
+ false
40
+ end
41
+ end
42
+
43
+ def cannot_edit?
44
+ ! can_edit?
45
+ end
46
+
47
+ def genders
48
+ { t(:'gender.female') => false, t(:'gender.male') => true }
49
+ end
50
+
51
+ def style_semester(date)
52
+ date.strftime('')
53
+ end
54
+
55
+ def required_field
56
+ content_tag :span, t(:required), class: 'label label-important pull-right'
57
+ end
58
+
59
+ def render_js_partial(partial, locals = {})
60
+ unless locals == {}
61
+ escape_javascript(render partial: partial, formats: [:html], handlers: [:erb, :slim], locals: locals)
62
+ else
63
+ escape_javascript(render partial: partial, formats: [:html], handlers: [:erb, :slim])
64
+ end
65
+ end
66
+
67
+ def title(text)
68
+ content_for(:title) do
69
+ text
70
+ end
71
+ end
72
+
73
+ def color_code(color)
74
+ content_tag :div, nil, style: "width:100px;height:20px;background-color:#{color}"
75
+ end
76
+
77
+
78
+
79
+ def comma_separated_list(objects, &block)
80
+ if objects.any?
81
+ objects.map do |object|
82
+ block_given? ? block.call(object) : object
83
+ end.join(', ').html_safe
84
+ else
85
+ t(:empty)
86
+ end
87
+ end
88
+
89
+ def prepare_target(nested_resource, address)
90
+ return nil if nested_resource.blank?
91
+ [nested_resource, address].flatten
92
+ end
93
+
94
+ def prepare_resource_name(nested_resources, resource)
95
+ @resource_name = [nested_resources.map {|r| r.is_a?(Symbol) ? r.to_s : get_class(r) }, resource.to_s].flatten.join '-'
96
+ end
97
+
98
+ def exam_completion_info(exam)
99
+ @course_students ||= @course.students
100
+ ungraded = exam.ungraded(@course_students)
101
+ total = exam.total_records(@course_students)
102
+
103
+ percentage = number_to_percentage exam.completion(@course_students), precision: 2
104
+
105
+ "#{t(:'exam.completion')}:#{percentage} #{t(:'exam.graded')}:#{total - ungraded} #{t(:'exam.ungraded')}:#{ungraded} #{t(:'exam.total')}:#{total}"
106
+ end
107
+
108
+ def datepicker_date_format(date)
109
+ date ? date.strftime('%Y-%m-%d') : Time.now.strftime('%Y-%m-%d')
110
+ end
111
+
112
+ def extract_grouped(grouped, resource)
113
+ grouped.map(&resource.to_sym)
114
+ end
115
+
116
+ def nested_header(text)
117
+ content_tag :h4, text
118
+ end
119
+
120
+ def state_load(object)
121
+ object.country.nil? ? Gaku::State.none : object.country.states
122
+ end
123
+
124
+ def disabled?(object)
125
+ object.new_record? || object.country.states.blank?
126
+ end
127
+
128
+ def link_to_download(resource, options = {})
129
+ name = content_tag(:span, nil, class: 'glyphicon glyphicon-download')
130
+ attributes = {
131
+ class: "btn btn-xs btn-success download-link"
132
+ }.merge(options)
133
+ link_to name, resource, attributes
134
+ end
135
+
136
+ def ajax_link_to_recovery(resource, options = {})
137
+ name = content_tag(:span, nil, class: 'glyphicon glyphicon-repeat')
138
+ attributes = {
139
+ remote: true,
140
+ class: "btn btn-xs btn-success recovery-link"
141
+ }.merge(options)
142
+ link_to name, resource, attributes
143
+ end
144
+
145
+ def icon(name)
146
+ content_tag(:span, nil, class: "#{name}")
147
+ end
148
+
149
+ def icon_label(icon_name, label)
150
+ raw %{ #{icon(icon_name)} #{label} }
151
+ end
152
+
153
+ end
154
+ end
155
+
@@ -8,7 +8,7 @@ module Gaku
8
8
 
9
9
  validates :student_id,
10
10
  uniqueness: {
11
- scope: %w( enrollable_type enrollable_id ),
11
+ scope: %i( enrollable_type enrollable_id ),
12
12
  message: I18n.t(:'student.already_enrolled')
13
13
  }
14
14
 
@@ -26,6 +26,9 @@ module Gaku
26
26
  after_destroy :refresh_positions
27
27
 
28
28
  before_update :weight_calculate
29
+ before_save :sanitize_score_selection_options
30
+
31
+ enum score_type: %i( score score_selection score_text )
29
32
 
30
33
  def to_s
31
34
  name
@@ -68,6 +71,12 @@ module Gaku
68
71
 
69
72
  private
70
73
 
74
+ def sanitize_score_selection_options
75
+ if self.score_selection_options
76
+ self.score_selection_options = self.score_selection_options.reject(&:blank?)
77
+ end
78
+ end
79
+
71
80
  def proper_position
72
81
  self.position = exam.exam_portions.count
73
82
  end
@@ -7,7 +7,7 @@ module Gaku
7
7
  validates :semester_id, :semesterable_type, :semesterable_id, presence: true
8
8
 
9
9
  validates :semester_id,
10
- uniqueness: { scope: %w( semesterable_type semesterable_id ), message: I18n.t(:'semester.already') }
10
+ uniqueness: { scope: %i( semesterable_id semesterable_type ), message: I18n.t(:'semester.already') }
11
11
 
12
12
  validates :semesterable_type,
13
13
  inclusion: { in: %w( Gaku::ClassGroup Gaku::Course ), message: '%{value} is not a valid' }
@@ -62,6 +62,10 @@ module Gaku
62
62
  where(enrollment_status_code: EnrollmentStatus.active.pluck(:code))
63
63
  end
64
64
 
65
+ def full_name
66
+ "#{name} #{surname}"
67
+ end
68
+
65
69
  def make_enrolled
66
70
  enrollment_status = EnrollmentStatus.where(
67
71
  code: 'enrolled',
@@ -0,0 +1,7 @@
1
+ = f.text_field :name, label: t(:'grading_method.name')
2
+ = f.text_field :description, label: t(:'grading_method.description')
3
+
4
+ /= f.text_field :method, label: t(:'grading_method.method')
5
+ = f.select :method, {"Score" => "score", "Percentage" => "percentage", "Ordinal" => "ordinal", "Interval" => "interval", "Ratio" => "ratio", "Pass/Fail" => "pass_fail"}, {prompt: "メソッドを選択してください"} , class: "form-control"
6
+
7
+ = render 'arguments_form_fields', f: f
@@ -0,0 +1,5 @@
1
+ .row
2
+ .col-md-6
3
+ = f.select :syllabus_id, options_from_collection_for_select(@syllabuses, :id, :name), {}, label: t(:'syllabus.singular'), class: 'form-control'
4
+ .col-md-6
5
+ = f.text_field :code, placeholder: t(:'course.code_sample'), label: t(:'course.code')
@@ -0,0 +1,5 @@
1
+ var jsonObject = '<%= @exam_portion_score.to_json.html_safe.to_s %>'
2
+ <% broadcast "/messages/new" do %>
3
+ $('#edit_exam_portion_score_<%= @exam_portion_score.id %>').children('input').val('<%= @exam_portion_score.score %>')
4
+ <% end %>
5
+