started implementing teams

This commit is contained in:
Hauke Klement
2015-01-28 12:28:09 +01:00
parent cf346e2271
commit dd624b26c8
25 changed files with 355 additions and 3 deletions

View File

@ -7,6 +7,7 @@ class ExercisesController < ApplicationController
before_action :set_execution_environments, only: [:create, :edit, :new, :update]
before_action :set_exercise, only: MEMBER_ACTIONS + [:clone, :implement, :run, :statistics, :submit]
before_action :set_file_types, only: [:create, :edit, :new, :update]
before_action :set_teams, only: [:create, :edit, :new, :update]
def authorize!
authorize(@exercise || @exercises)
@ -49,7 +50,7 @@ class ExercisesController < ApplicationController
end
def exercise_params
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :title, files_attributes: file_attributes).merge(user_id: current_user.id, user_type: current_user.class.name)
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :team_id, :title, files_attributes: file_attributes).merge(user_id: current_user.id, user_type: current_user.class.name)
end
private :exercise_params
@ -114,6 +115,11 @@ class ExercisesController < ApplicationController
end
private :set_file_types
def set_teams
@teams = Team.all.order(:name)
end
private :set_teams
def show
end

View File

@ -0,0 +1,69 @@
class TeamsController < ApplicationController
before_action :set_team, only: MEMBER_ACTIONS
def authorize!
authorize(@team || @teams)
end
private :authorize!
def create
@team = Team.new(team_params)
authorize!
respond_to do |format|
if @team.save
format.html { redirect_to(team_path(@team.id), notice: t('shared.object_created', model: Team.model_name.human)) }
format.json { render(:show, location: @team, status: :created) }
else
format.html { render(:new) }
format.json { render(json: @team.errors, status: :unprocessable_entity) }
end
end
end
def destroy
@team.destroy
respond_to do |format|
format.html { redirect_to(teams_path, notice: t('shared.object_destroyed', model: Team.model_name.human)) }
format.json { head(:no_content) }
end
end
def edit
end
def index
@teams = Team.all.order(:name)
authorize!
end
def new
@team = Team.new
authorize!
end
def set_team
@team = Team.find(params[:id])
authorize!
end
private :set_team
def show
end
def team_params
params[:team].permit(:name, internal_user_ids: [])
end
private :team_params
def update
respond_to do |format|
if @team.update(team_params)
format.html { redirect_to(team_path(@team.id), notice: t('shared.object_updated', model: Team.model_name.human)) }
format.json { render(:show, location: @team, status: :ok) }
else
format.html { render(:edit) }
format.json { render(json: @team.errors, status: :unprocessable_entity) }
end
end
end
end

View File

@ -7,6 +7,7 @@ class Exercise < ActiveRecord::Base
belongs_to :execution_environment
has_many :submissions
belongs_to :team
has_many :users, source_type: ExternalUser, through: :submissions
scope :with_submissions, -> { where('id IN (SELECT exercise_id FROM submissions)') }

View File

@ -3,6 +3,8 @@ class InternalUser < ActiveRecord::Base
authenticates_with_sorcery!
has_and_belongs_to_many :teams
validates :email, presence: true, uniqueness: true
validates :password, confirmation: true, on: :update, presence: true, unless: :activated?
validates :role, inclusion: {in: ROLES}

10
app/models/team.rb Normal file
View File

@ -0,0 +1,10 @@
class Team < ActiveRecord::Base
has_and_belongs_to_many :internal_users
alias_method :members, :internal_users
validates :name, presence: true
def to_s
name
end
end

View File

@ -0,0 +1,14 @@
class TeamPolicy < ApplicationPolicy
[:create?, :index?, :new?].each do |action|
define_method(action) { @user.internal? }
end
[:destroy?, :edit?, :show?, :update?].each do |action|
define_method(action) { admin? || member? }
end
def member?
@record.members.include?(@user)
end
private :member?
end

View File

@ -5,7 +5,7 @@
= t('shared.administration')
span.caret
ul.dropdown-menu role='menu'
- models = [ExecutionEnvironment, Exercise, Consumer, ExternalUser, FileType, InternalUser, Submission].sort_by { |model| model.model_name.human(count: 2) }
- models = [ExecutionEnvironment, Exercise, Consumer, ExternalUser, FileType, InternalUser, Submission, Team].sort_by { |model| model.model_name.human(count: 2) }
- models.each do |model|
- if policy(model).index?
li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))

View File

@ -13,6 +13,9 @@
= f.label(:instructions)
= f.hidden_field(:instructions)
.form-control.markdown
.form-group
= f.label(:team_id)
= f.collection_select(:team_id, @teams, :id, :name, {include_blank: true}, class: 'form-control')
.checkbox
label
= f.check_box(:public)

View File

@ -11,6 +11,7 @@ h1
= row(label: 'exercise.description', value: @exercise.description)
= row(label: 'exercise.execution_environment', value: link_to(@exercise.execution_environment, @exercise.execution_environment))
= row(label: 'exercise.instructions', value: render_markdown(@exercise.instructions))
= row(label: 'exercise.team', value: @exercise.team ? link_to(@exercise.team, @exercise.team) : nil)
= row(label: 'exercise.maximum_score', value: @exercise.maximum_score)
= row(label: 'exercise.public', value: @exercise.public?)
= row(label: 'exercise.embedding_parameters') do

View File

@ -0,0 +1,9 @@
= form_for(@team) do |f|
= render('shared/form_errors', object: @team)
.form-group
= f.label(:name)
= f.text_field(:name, class: 'form-control', required: true)
.form-group
= f.label(:internal_user_ids)
= f.collection_select(:internal_user_ids, InternalUser.all.order(:name), :id, :name, {}, {class: 'form-control', multiple: true})
.actions = render('shared/submit_button', f: f, object: @team)

View File

@ -0,0 +1,3 @@
h1 = @hint
= render('form')

View File

@ -0,0 +1,19 @@
h1 = Team.model_name.human(count: 2)
.table-responsive
table.table
thead
tr
th = t('activerecord.attributes.team.name')
th = t('activerecord.attributes.team.internal_user_ids')
th colspan=3 = t('shared.actions')
tbody
- @teams.each do |team|
tr
td = team.name
td = team.members.count
td = link_to(t('shared.show'), team_path(team.id))
td = link_to(t('shared.edit'), edit_team_path(team.id))
td = link_to(t('shared.destroy'), team_path(team.id), data: {confirm: t('shared.confirm_destroy')}, method: :delete)
p = render('shared/new_button', model: Team, path: new_team_path)

View File

@ -0,0 +1,3 @@
h1 = t('shared.new_model', model: Team.model_name.human)
= render('form')

View File

@ -0,0 +1,9 @@
h1
= @team
= render('shared/edit_button', object: @team, path: edit_team_path(@team.id))
= row(label: 'team.name', value: @team.name)
= row(label: 'team.internal_user_ids') do
ul.list-unstyled
- @team.members.order(:name).each do |internal_user|
li = link_to(internal_user, internal_user)