Class: Api::ChallengesController

Inherits:
ApplicationController show all
Includes:
Affiliation, ExternalLinks, Faq, Follow, Hooks, Media, Members, Recommendations, Relations, Upload, Utils
Defined in:
app/controllers/api/challenges_controller.rb

Instance Method Summary collapse

Methods included from Utils

#get_id_from_short_title, #is_admin, #is_member, #is_reviewer, #nickname_exist, #short_title_exist

Methods included from Upload

#remove_avatar, #remove_banner, #remove_document, #upload_avatar, #upload_banner, #upload_document

Methods included from Relations

#clap, #clappers, #follow, #review, #reviewed_object, #save, #saved_objects

Methods included from Recommendations

#recommended, #similar

Methods included from Members

#get_current_role, #get_roles_list, #has_membership, #invite, #invite_as_admin, #join, #leave, #members_list, #remove_member, #update_member

Methods included from Media

#media_create, #media_destroy, #media_index, #media_show, #media_update, #media_upload

Methods included from Hooks

#create_external_hook, #delete_external_hook, #get_external_hooks, #hook_new_member, #hook_new_need, #hook_new_post, #hook_new_project, #hook_new_project_challenge, #update_external_hook

Methods included from Follow

#followers, #following

Methods included from Faq

#faq_create, #faq_destroy, #faq_index, #faq_show, #faq_update

Methods included from ExternalLinks

#create_link, #destroy_link, #index_link, #update_link

Methods included from Affiliation

#affiliation_create, #affiliation_destroy, #affiliation_index, #affiliation_show, #affiliation_update

Methods included from Response

#json_response

Instance Method Details

#attachObject

This method add project to a challenge and changes its status



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'app/controllers/api/challenges_controller.rb', line 83

def attach
  if @challenge.projects.include?(@project)
    render json: { data: "Project id:#{@project.id} is already attached" }, status: :ok
  else
    @challenge.projects << @project
    @project.add_edge(@challenge, 'is_part_of')
    find_project_relation
    @relation.project_status = 'pending'
    @relation.save!
    hook_new_project_challenge(@challenge.externalhooks, @project)
    render json: { data: "Project id:#{@project.id} attached" }, status: :ok
  end
end

#can_createObject



40
41
42
43
44
45
46
# File 'app/controllers/api/challenges_controller.rb', line 40

def can_create
  if can_access
    render json: { data: 'Authorized' }, status: :ok
  else
    render json: { data: 'Forbidden' }, status: :forbidden
  end
end

#createObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'app/controllers/api/challenges_controller.rb', line 48

def create
  render(json: { data: 'Forbidden' }, status: :forbidden) && return unless can_access

  @challenge = Challenge.new(challenge_params)
  if @challenge.save
    current_user.add_edge(@challenge, 'is_author_of')
    update_skills_interests
    current_user.add_role :owner, @challenge
    current_user.add_role :admin, @challenge
    current_user.add_role :member, @challenge
    current_user.add_edge(@challenge, 'is_member_of')
    current_user.add_edge(@challenge, 'is_admin_of')
    current_user.add_edge(@challenge, 'is_owner_of')
    render json: @challenge, status: :created
  else
    render json: { data: 'Something went wrong' }, status: :unprocessable_entity
  end
end

#destroyObject



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/controllers/api/challenges_controller.rb', line 159

def destroy
  # NOTE: a challenge with 1 user is considered a test challenge, and can be destroyed
  if @challenge.users.count == 1 && current_user.has_role?(:owner, @challenge)
    @challenge.destroy
    current_user.remove_edge(@challenge, 'is_author_of')
    current_user.remove_edge(@challenge, 'is_member_of')
    current_user.remove_edge(@challenge, 'is_admin_of')
    current_user.remove_edge(@challenge, 'is_owner_of')
    render json: { data: "Challenge id:#{params[:id]} destroyed" }, status: :ok
  elsif current_user.has_role?(:owner, @challenge)
    @challenge.archived!
    render json: { data: "Challenge id:#{params[:id]} archived" }, status: :ok
  else
    render json: { data: 'You are not authorized to do that' }, status: :unauthorized
  end
end

#indexObject



27
28
29
30
# File 'app/controllers/api/challenges_controller.rb', line 27

def index
  @pagy, @challenges = pagy(Challenge.where.not(status: 'draft').all)
  render json: @challenges, controller: true
end

#index_needsObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'app/controllers/api/challenges_controller.rb', line 128

def index_needs
  # Only take accepted projects into account
  needs = Need
          .joins(project: :challenges_projects)
          .distinct
          .where('challenge_id = ?', @challenge.id)
          .where(challenges_projects: { project_status: ChallengesProject.project_statuses[:accepted] })
          .order(id: :desc) # can't use created_at since some records don't have it

  @pagy, records = pagy(needs)
  render json: Panko::Response.new(
    needs: Panko::ArraySerializer.new(
      records,
      each_serializer: Api::SharedNeedSerializer,
      context: { current_user: current_user }
    )
  )
end

#index_projectsObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/controllers/api/challenges_controller.rb', line 109

def index_projects
  # Don't take archived projects into account
  projects = Project
             .joins(:challenges)
             .distinct
             .where(challenges: { id: @challenge.id })
             .where.not(status: :archived)
             .order(id: :desc) # can't use created_at since some records don't have it

  @pagy, records = pagy(projects)
  render json: Panko::Response.new(
    projects: Panko::ArraySerializer.new(
      records,
      each_serializer: Api::SharedProjectSerializer,
      context: { current_user: current_user, challenge_id: @challenge.id }
    )
  )
end

#members_shortObject



176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'app/controllers/api/challenges_controller.rb', line 176

def members_short
  render json: @challenge.all_owners_admins_members.map { |m|

    # Map through member's projects, and return ids of those whose one of the challenges have their id equals to current challenge id of route
    projects = m.projects.map do |project|
      !project.challenges.empty? && project.challenges.map { |challenge| challenge.id == @challenge.id && project.id}.select(&:itself)[0]
    end
    
    # Form the member json
    { id: m.id, first_name: m.first_name, last_name: m.last_name, email: m.email, projects: projects.select(&:itself) }
    
  }, status: :ok
end

#my_challengesObject



32
33
34
35
36
37
38
# File 'app/controllers/api/challenges_controller.rb', line 32

def my_challenges
  @challenges = Challenge.with_role(:owner, current_user)
  @challenges += Challenge.with_role(:admin, current_user)
  @challenges += Challenge.with_role(:member, current_user)
  @pagy, @challenges = pagy_array(@challenges.uniq)
  render json: @challenges
end

#removeObject

The object relation is removed with no status change



98
99
100
101
102
103
104
105
106
107
# File 'app/controllers/api/challenges_controller.rb', line 98

def remove
  if @challenge.projects.include?(@project)
    @challenge.projects.delete(@project)
    @project.remove_edge(@challenge, 'is_part_of')
    @project&.index! # manually reindex project to aglgolia
    render json: { data: "Project id:#{@project.id} removed" }, status: :ok
  else
    render json: { data: "Project id:#{@project.id} is not attached" }, status: :not_found
  end
end

#set_project_statusObject



147
148
149
150
151
152
153
154
155
156
157
# File 'app/controllers/api/challenges_controller.rb', line 147

def set_project_status
  render json: { data: "Status invalid. Valid statuses include: #{Project.statuses.keys}." } if params[:status] != 'accepted'

  @relation.accepted!
  @challenge.add_users_from_projects
  @challenge.program&.add_user_from_challenges
  
  @project&.index! # manually reindex project to aglgolia

  render json: { data: 'Status updated' }, status: :ok
end

#showObject



67
68
69
# File 'app/controllers/api/challenges_controller.rb', line 67

def show
  render json: @challenge, show_objects: true, controller: true
end

#updateObject



71
72
73
74
75
76
77
78
79
80
# File 'app/controllers/api/challenges_controller.rb', line 71

def update
  render(json: { data: 'You are not an admin of this challenge' }, status: :forbidden) && return unless current_user.has_role? :admin, @challenge

  if @challenge.update(challenge_params)
    update_skills_interests
    render json: { data: "Challenge id:#{@challenge.id} has been updated" }, status: :ok, controller: true
  else
    render json: { data: 'Something went wrong' }, status: :unprocessable_entity
  end
end