Class RubricCriterion
In: app/models/rubric_criterion.rb
Parent: ActiveRecord::Base

Methods

Constants

RUBRIC_LEVELS = 5   Just a small effort here to remove magic numbers…
DEFAULT_WEIGHT = 1.0
DEFAULT_LEVELS = [ {'name'=> I18n.t("rubric_criteria.defaults.level_0"), 'description'=> I18n.t("rubric_criteria.defaults.description_0")}, {'name'=> I18n.t("rubric_criteria.defaults.level_1"), 'description'=> I18n.t("rubric_criteria.defaults.description_1")}, {'name'=> I18n.t("rubric_criteria.defaults.level_2"), 'description'=> I18n.t("rubric_criteria.defaults.description_2")}, {'name'=> I18n.t("rubric_criteria.defaults.level_3"), 'description'=> I18n.t("rubric_criteria.defaults.description_3")}, {'name'=> I18n.t("rubric_criteria.defaults.level_4"), 'description'=> I18n.t("rubric_criteria.defaults.description_4")}

Public Class methods

Returns an array containing the criterion names that didn‘t exist

[Source]

     # File app/models/rubric_criterion.rb, line 237
237:   def self.assign_tas_by_csv(csv_file_contents, assignment_id)
238:     failures = []
239:     FasterCSV.parse(csv_file_contents) do |row|
240:       criterion_name = row.shift # Knocks the first item from array
241:       criterion = RubricCriterion.find_by_assignment_id_and_rubric_criterion_name(assignment_id, criterion_name)
242:       if criterion.nil?
243:         failures.push(criterion_name)
244:       else
245:         criterion.add_tas_by_user_name_array(row) # The rest of the array
246:       end
247:     end
248:     return failures
249:   end

Create a CSV string from all the rubric criteria related to an assignment.

Returns:

A string. See create_or_update_from_csv_row for format reference.

[Source]

    # File app/models/rubric_criterion.rb, line 78
78:   def self.create_csv(assignment)
79:     csv_string = FasterCSV.generate do |csv|
80:       assignment.rubric_criteria.each do |criterion|
81:         criterion_array = [criterion.rubric_criterion_name,criterion.weight]
82:         (0..RUBRIC_LEVELS - 1).each do |i|
83:           criterion_array.push(criterion['level_' + i.to_s + '_name'])
84:         end
85:         (0..RUBRIC_LEVELS - 1).each do |i|
86:           criterion_array.push(criterion['level_' + i.to_s + '_description'])
87:         end
88:         csv << criterion_array
89:       end
90:     end
91:     return csv_string
92:   end

Instantiate a RubricCriterion from a CSV row and attach it to the supplied assignment.

Params:

row:An array representing one CSV file row. Should be in the following format: [name, weight, names, descriptions] where the names part must contain RUBRIC_LEVELS elements representing the name of each level and the descriptions part (optional) can contain up to RUBRIC_LEVELS description (one for each level).
assignment:The assignment to which the newly created criterion should belong.

Raises:

RuntimeError If the row does not contains enough information, if the weight value

                          is zero (or doesn't evaluate to a float)

[Source]

     # File app/models/rubric_criterion.rb, line 110
110:   def self.create_or_update_from_csv_row(row, assignment)
111:     if row.length < RUBRIC_LEVELS + 2
112:       raise I18n.t('criteria_csv_error.incomplete_row')
113:     end
114:     working_row = row.clone
115:     rubric_criterion_name = working_row.shift
116:     # If a RubricCriterion of the same name exits, load it up.  Otherwise,
117:     # create a new one.
118:     criterion = assignment.rubric_criteria.find_or_create_by_rubric_criterion_name(rubric_criterion_name)
119:     #Check that the weight is not a string.
120:     begin
121:       criterion.weight = Float(working_row.shift)
122:     rescue ArgumentError => e
123:       raise I18n.t('criteria_csv_error.weight_not_number')
124:     end
125:     # Only set the position if this is a new record.
126:     if criterion.new_record?
127:       criterion.position = assignment.next_criterion_position
128:     end
129:     # next comes the level names.
130:     (0..RUBRIC_LEVELS-1).each do |i|
131:       criterion['level_' + i.to_s + '_name'] = working_row.shift
132:     end
133:     # the rest of the values are level descriptions.
134:     working_row.each_with_index do |desc, i|
135:       criterion['level_' + i.to_s + '_description'] = desc
136:     end
137:     if !criterion.save
138:       raise RuntimeError.new(criterion.errors)
139:     end
140:     return criterion
141:   end

Parse a rubric criteria CSV file.

Params:

file:A file object which will be tried for parsing.
assignment:The assignment to which the new criteria should belong to.
invalid_lines:An object to recieve all encountered invalid lines. Strings representing the faulty line followed by a human readable error message are appended to the object via the << operator.

Hint: An array allows for an easy access of single invalid lines.

Returns:

The number of successfully created criteria.

[Source]

     # File app/models/rubric_criterion.rb, line 159
159:   def self.parse_csv(file, assignment, invalid_lines)
160:     nb_updates = 0
161:     FasterCSV.parse(file.read) do |row|
162:       next if FasterCSV.generate_line(row).strip.empty?
163:       begin
164:         RubricCriterion.create_or_update_from_csv_row(row, assignment)
165:         nb_updates += 1
166:       rescue RuntimeError => e
167:         invalid_lines << row.join(',') + ": " + e.message unless invalid_lines.nil?
168:       end
169:     end
170:     return nb_updates
171:   end

Public Instance methods

[Source]

     # File app/models/rubric_criterion.rb, line 190
190:   def add_tas(ta_array)
191:     ta_array = Array(ta_array)
192:     associations = criterion_ta_associations.all(:conditions => {:ta_id => ta_array})
193:     ta_array.each do |ta|
194:       # & is the mathematical set intersection operator between two arrays
195:       if (ta.criterion_ta_associations & associations).size < 1
196:         criterion_ta_associations.create(:ta => ta, :criterion => self, :assignment => self.assignment)
197:       end
198:     end
199:   end

[Source]

     # File app/models/rubric_criterion.rb, line 230
230:   def add_tas_by_user_name_array(ta_user_name_array)
231:     result = ta_user_name_array.map{|ta_user_name|
232:       Ta.find_by_user_name(ta_user_name)}.compact
233:     add_tas(result)
234:   end

[Source]

     # File app/models/rubric_criterion.rb, line 182
182:   def all_assigned_groups
183:     result = []
184:     tas.each do |ta|
185:       result = result.concat(ta.get_groupings_by_assignment(assignment))
186:     end
187:     return result.uniq
188:   end

[Source]

     # File app/models/rubric_criterion.rb, line 202
202:   def get_name
203:     return rubric_criterion_name
204:   end

[Source]

     # File app/models/rubric_criterion.rb, line 219
219:   def get_ta_names
220:     return criterion_ta_associations.collect {|association| association.ta.user_name}
221:   end

[Source]

     # File app/models/rubric_criterion.rb, line 173
173:   def get_weight
174:     return self.weight
175:   end

[Source]

     # File app/models/rubric_criterion.rb, line 223
223:   def has_associated_ta?(ta)
224:     if !ta.ta?
225:       return false
226:     end
227:     return !(criterion_ta_associations.find_by_ta_id(ta.id) == nil)
228:   end

[Source]

    # File app/models/rubric_criterion.rb, line 44
44:   def mark_for(result_id)
45:     return marks.find_by_result_id(result_id)
46:   end

[Source]

     # File app/models/rubric_criterion.rb, line 206
206:   def remove_tas(ta_array)
207:     ta_array = Array(ta_array)
208:     associations_for_criteria = criterion_ta_associations.all(:conditions => {:ta_id => ta_array})
209:     ta_array.each do |ta|
210:       # & is the mathematical set intersection operator between two arrays
211:       assoc_to_remove = (ta.criterion_ta_associations & associations_for_criteria)
212:       if assoc_to_remove.size > 0
213:         criterion_ta_associations.delete(assoc_to_remove)
214:         assoc_to_remove.first.destroy
215:       end
216:     end
217:   end

[Source]

     # File app/models/rubric_criterion.rb, line 177
177:   def round_weight
178:     factor = 10.0 ** 3
179:     self.weight = (self.weight * factor).round.to_f / factor
180:   end

[Source]

    # File app/models/rubric_criterion.rb, line 48
48:   def set_default_levels
49:     DEFAULT_LEVELS.each_with_index do |level, index|
50:       self['level_' + index.to_s + '_name'] = level['name']
51:       self['level_' + index.to_s + '_description'] = level['description']
52:     end
53:   end

Set all the level names at once and saves the object.

Params:

levels:An array containing every level name. A rubric criterion contains RUBRIC_LEVELS levels. If the array is smaller, only the first levels are set. If the array is bigger, higher indexes are ignored.

Returns:

Wether the save operation was successful or not.

[Source]

    # File app/models/rubric_criterion.rb, line 66
66:   def set_level_names(levels)
67:     levels.each_with_index do |level, index|
68:       self['level_' + index.to_s + '_name'] = level
69:     end
70:     save
71:   end

[Source]

    # File app/models/rubric_criterion.rb, line 21
21:   def update_assigned_groups_count
22:     result = []
23:     criterion_ta_associations.each do |cta|
24:       result = result.concat(cta.ta.get_groupings_by_assignment(assignment))
25:     end
26:     self.assigned_groups_count = result.uniq.length
27:   end

[Source]

    # File app/models/rubric_criterion.rb, line 29
29:   def validate_total_weight
30:     errors.add(:assignment, I18n.t("rubric_criteria.error_total")) if self.assignment.total_mark + (4 * (self.weight - self.weight_was)) <= 0
31:   end

[Validate]