aboutsummaryrefslogtreecommitdiff
blob: c4e8a9311103b89a506ff2657b025967dbfdd587 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
require 'permissions/owned_model.rb'
require 'permissions/set.rb'
class Answer < ActiveRecord::Base

  hobo_model # Don't put anything above this

  fields do
    content   HoboFields::MarkdownString
    approved  :boolean, :default => false
    reference :boolean, :default => false
    feedback  HoboFields::EnumString.for('', 'Documentation ok',
                  'Could not find documentation', 'Documentation insufficient'),
                  :default => ''
    timestamps
  end

  attr_readonly :reference
  belongs_to    :question
  has_many      :comments

  named_scope   :of_mentored_by, lambda { |mentor| {
    :joins => :owner, :conditions => { 'users.mentor_id', mentor } } }

  named_scope   :in_category, lambda { |category| {
    :joins => :question, :conditions => { 'questions.question_category_id', category} } }

  validates_uniqueness_of :question_id, :scope => :reference, :if => :reference
  validates_uniqueness_of :question_id, :scope => :owner_id, :unless => :reference

  owned_model owner_class = "User"

  before_validation do |record|
    record.approved = false if record.content_changed?
  end

  after_create :notify_new_answer
  after_update :notify_changed_answer

  multi_permission :update, :destroy do
    # It's fine to change correct, because it's ignored in non-email answers
    # and email answers have separate permissions
    (owned? && !reference && !approved) ||
    (reference && acting_user.role.is_recruiter?) ||
    (only_changed?(:approved, :correct) && owner.mentor_is?(acting_user))
  end

  def create_permitted?
    (owned_soft? && !reference)||(reference && acting_user.role.is_recruiter?)
  end

  # Proper edit permissions can't be deduced, because we need to access value
  # of some fields to set them
  def edit_permitted?(field)
    owned_soft? ||
    owner.mentor_is?(acting_user) ||
    (reference && acting_user.signed_up? && acting_user.role.is_recruiter?)
  end

  def content_edit_permitted?
    owned_soft? ||
    (reference && acting_user.signed_up? && acting_user.role.is_recruiter?)
  end

  def approved_edit_permitted?
    owner.mentor_is?(acting_user)
  end

  def reference_edit_permitted?
    acting_user.try.role.try.is_recruiter?
  end

  def view_permitted?(field)
    owned_soft? ||
      acting_user.try.role.try.is_recruiter? ||
      owner.mentor_is?(acting_user)
  end

  def self.update_from(params)
   ans = Answer.find(params['id'])

  if ans.class == Answer
    update = params["answer"] || []
  elsif ans.class == MultipleChoiceAnswer
    params["multiple_choice_answer"] = {} unless params["multiple_choice_answer"]
    params["multiple_choice_answer"]["options"] = params["options"].inject(Array.new){ |a, cur| a.push cur.to_i }
    update = params["multiple_choice_answer"]
  end

   result = ans.attributes

   for u in update
    result[u[0]] = u[1]
   end

   result
  end

  def self.new_from(params)

    if params.include? "answer"
      Answer.new params["answer"]
    elsif params.include? "multiple_choice_answer"
      ans_hash            = params["multiple_choice_answer"]
      new_ans             = MultipleChoiceAnswer.new  ans_hash
      new_ans.options     = params["options"].try.inject(Array.new){ |a, cur| a.push cur.to_i } || []
      return new_ans
    end

  end

  def self.wrong_answers_of(uid)
    Answer.find_by_sql ["SELECT ans.* FROM answers ans, answers ref WHERE
      ref.reference = 't' AND ans.question_id = ref.question_id AND
      ans.content != ref.content AND ans.owner_id = ?", uid]
  end

  protected
    def notify_new_answer
      UserMailer.deliver_new_answer(owner.mentor, self) unless owner.try.mentor.nil?
    end

    def notify_changed_answer
      UserMailer.deliver_changed_answer(owner.mentor, self) unless owner.try.mentor.nil?
    end

end