Skip to content

Commit

Permalink
Program questionnaires relation edit
Browse files Browse the repository at this point in the history
  • Loading branch information
mpugach committed Feb 28, 2023
1 parent c6f5c87 commit 3e2b87d
Show file tree
Hide file tree
Showing 21 changed files with 139 additions and 21 deletions.
1 change: 1 addition & 0 deletions app/assets/javascripts/select_2_initializers.js.coffee
Expand Up @@ -59,3 +59,4 @@ $ ->
simpleSelect($('select#class_schedule_academic_group_ids'), 'academic_groups')
simpleSelect($('select#class_schedule_classroom_id'), 'classrooms')
simpleSelect($('select#class_schedule_course_id'), 'courses')
simpleSelect($('select#program_questionnaire_ids'), 'questionnaires')
10 changes: 8 additions & 2 deletions app/controllers/programs_controller.rb
Expand Up @@ -27,14 +27,15 @@ def create
@program = Program.new(program_params)

authorize @program

@program.save
reset_questionnaires_count

respond_with(@program, location: programs_path)
end

def update
@program.update(program_params)
reset_questionnaires_count

respond_with(@program, location: programs_path)
end
Expand Down Expand Up @@ -75,7 +76,8 @@ def program_params
:description_ru,
:visible,
:position,
:manager_id
:manager_id,
questionnaire_ids: []
)

permitted[:title_uk].strip!
Expand All @@ -85,4 +87,8 @@ def program_params

permitted
end

def reset_questionnaires_count
Program.reset_counters(@program.id, :questionnaires_count) if @program.persisted?
end
end
9 changes: 9 additions & 0 deletions app/controllers/ui/questionnaires_controller.rb
@@ -0,0 +1,9 @@
module Ui
class QuestionnairesController < Ui::BaseController
def index
authorize Questionnaire, :ui_index?

respond_with_interaction Ui::QuestionnairesLoadingInteraction
end
end
end
17 changes: 17 additions & 0 deletions app/interactions/ui/questionnaires_loading_interaction.rb
@@ -0,0 +1,17 @@
module Ui
class QuestionnairesLoadingInteraction < BaseInteraction
include IdAndTitleLoadable

def init
@json_root = :questionnaires
@resource = Questionnaire.ilike("title_#{user.locale}", params[:q])
end

def serialize_resource(questionnaire)
{
id: questionnaire.id,
text: questionnaire["title_#{user.locale}"]
}
end
end
end
3 changes: 2 additions & 1 deletion app/models/program.rb
@@ -1,8 +1,9 @@
class Program < ApplicationRecord
has_many :study_applications, dependent: :destroy
has_many :programs_questionnaires, dependent: :destroy

belongs_to :manager, class_name: 'Person'
has_and_belongs_to_many :questionnaires
has_many :questionnaires, through: :programs_questionnaires

validates :title_uk, :title_ru, :description_uk, :description_ru, :manager, presence: true

Expand Down
6 changes: 6 additions & 0 deletions app/models/programs_questionnaire.rb
@@ -0,0 +1,6 @@
class ProgramsQuestionnaire < ApplicationRecord
belongs_to :program, counter_cache: :questionnaires_count
belongs_to :questionnaire

has_paper_trail
end
5 changes: 4 additions & 1 deletion app/models/questionnaire.rb
@@ -1,9 +1,12 @@
class Questionnaire < ApplicationRecord
include Ilikable

serialize :rule, Hash

has_and_belongs_to_many :programs
has_many :programs_questionnaires, dependent: :destroy, class_name: 'ProgramsQuestionnaire'
has_many :questions, dependent: :destroy
has_many :questionnaire_completenesses, dependent: :destroy
has_many :programs, through: :programs_questionnaires
has_many :people, through: :questionnaire_completenesses

accepts_nested_attributes_for :questions
Expand Down
4 changes: 4 additions & 0 deletions app/policies/questionnaire_policy.rb
Expand Up @@ -17,6 +17,10 @@ def save_answers?
owned? || update_all?
end

def ui_index?
(user_activities & ['program:update', 'program:create']).any?
end

private

def owned?
Expand Down
6 changes: 6 additions & 0 deletions app/views/programs/_form.html.haml
Expand Up @@ -23,6 +23,12 @@
= f.association :manager, label_method: :complex_name, collection: [f.object.manager].compact,
input_html: { data: { placeholder: t('.select_manager_placeholder'), 'ajax--url': ui_group_admins_path } }

= f.association :questionnaires,
label_method: :"title_#{locale}",
collection: f.object.questionnaires,
hint: t('.questionnaires_hint'),
input_html: { data: { placeholder: t('.select_questionnaires_placeholder'), 'ajax--url': ui_questionnaires_path } }

.form-actions
= f.button :button, class: 'btn btn-submit col-xs-12' do
%span.glyphicon.glyphicon-refresh.spinner{ aria: { hidden: true } }
Expand Down
4 changes: 4 additions & 0 deletions app/views/programs/index.html.haml
Expand Up @@ -25,6 +25,8 @@
= t('.program_visibility')
= inline_info(t('.program_visibility_help'))

%th.text-top.text-center= t('.program_questionnaires_count')

- if @programs.any? { |program| policy(program).tap { |p| break p.edit? || p.destroy? } }
%th.text-top.text-right= t('.actions')

Expand All @@ -46,6 +48,8 @@
%td.text-center
= t(".program_visibility_#{program.visible}")

%td.text-center= program.questionnaires_count

- if policy(program).tap { |p| break p.edit? || p.destroy? }
%td.col-xs-2.col-sm-3.col-md-2.text-right
= link_to_edit(policy(program).edit?, edit_program_path(program))
Expand Down
1 change: 1 addition & 0 deletions config/locales/active_record.ru.yml
Expand Up @@ -58,6 +58,7 @@ ru:
visible: 'Видимость студентам'
position: 'Позиция сортировки'
manager: 'Администратор курса'
questionnaires: 'Опросники'
telephones:
phone: 'Телефонний номер'
questions/answers:
Expand Down
1 change: 1 addition & 0 deletions config/locales/active_record.uk.yml
Expand Up @@ -58,6 +58,7 @@ uk:
visible: 'Видимість студентам'
position: 'Позиція для сортування'
manager: 'Адміністратор курсу'
questionnaires: 'Опитувальники'
telephones:
phone: 'Телефонний номер'
questions/answers:
Expand Down
3 changes: 3 additions & 0 deletions config/locales/general.ru.yml
Expand Up @@ -203,12 +203,15 @@ ru:
program_visibility_help: 'Не видимый курс видят администраторы, но он не предлагается студентам, чтобы подать на него заявление'
program_visibility_true: 'Да'
program_visibility_false: 'Не видимый курс'
program_questionnaires_count: 'Количество опросников'
actions: 'Действия'
new:
title: 'Создание нового учебного курса'
submit: 'Создать'
form:
select_manager_placeholder: 'Выберите администратора курса'
select_questionnaires_placeholder: 'Добавьте опросники'
questionnaires_hint: 'Эти опросники автоматически назначаются студенту после того, как он подает заявление на этот курс'
edit:
title: 'Редактирование учебного курса'
submit: 'Сохранить'
Expand Down
3 changes: 3 additions & 0 deletions config/locales/general.uk.yml
Expand Up @@ -203,12 +203,15 @@ uk:
program_visibility_help: 'Не видимий курс бачать адміністратори, але він не пропонується стунтам, щоб подати на нього заяву'
program_visibility_true: 'Так'
program_visibility_false: 'Невидимий курс'
program_questionnaires_count: 'Кількість опитувальників'
actions: 'Дії'
new:
title: 'Створення нового учбового курсу'
submit: 'Створити'
form:
select_manager_placeholder: 'Оберіть адміністратора курсу'
select_questionnaires_placeholder: 'Додайте опитувальники'
questionnaires_hint: 'Ці опитувальники автоматично назначаються студенту, після того як він подає заяву на цей курс'
edit:
title: 'Редагування учбового курсу'
submit: 'Зберегти'
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Expand Up @@ -78,6 +78,7 @@
resources :classrooms, only: :index
resources :courses, only: :index
resources :teacher_profiles, only: :index
resources :questionnaires, only: :index
resources :examination_results, only: %i[create update destroy]
resources :schedule_attendances, only: %i[index create update destroy]

Expand Down
@@ -0,0 +1,12 @@
class AddPrimaryKeyToProgramsQuestionnaires < ActiveRecord::Migration[5.0]
def change
add_column :programs_questionnaires, :id, :primary_key

add_index(
:programs_questionnaires,
[:program_id, :questionnaire_id],
unique: true,
name: 'index_programs_questionnaires_on_p_and_q'
)
end
end
@@ -0,0 +1,5 @@
class AddQuestionnairesCountToPrograms < ActiveRecord::Migration[5.0]
def change
add_column :programs, :questionnaires_count, :integer, default: 0
end
end
6 changes: 4 additions & 2 deletions db/schema.rb
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20230225063808) do
ActiveRecord::Schema.define(version: 20230226201309) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -228,11 +228,13 @@
t.integer "manager_id"
t.integer "position"
t.integer "study_applications_count", default: 0
t.integer "questionnaires_count", default: 0
end

create_table "programs_questionnaires", id: false, force: :cascade do |t|
create_table "programs_questionnaires", force: :cascade do |t|
t.integer "questionnaire_id"
t.integer "program_id"
t.index ["program_id", "questionnaire_id"], name: "index_programs_questionnaires_on_p_and_q", unique: true, using: :btree
end

create_table "questionnaire_completenesses", force: :cascade do |t|
Expand Down
51 changes: 48 additions & 3 deletions db/structure.sql
Expand Up @@ -751,7 +751,8 @@ CREATE TABLE public.programs (
visible boolean DEFAULT false,
manager_id integer,
"position" integer,
study_applications_count integer DEFAULT 0
study_applications_count integer DEFAULT 0,
questionnaires_count integer DEFAULT 0
);


Expand Down Expand Up @@ -780,10 +781,30 @@ ALTER SEQUENCE public.programs_id_seq OWNED BY public.programs.id;

CREATE TABLE public.programs_questionnaires (
questionnaire_id integer,
program_id integer
program_id integer,
id integer NOT NULL
);


--
-- Name: programs_questionnaires_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--

CREATE SEQUENCE public.programs_questionnaires_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;


--
-- Name: programs_questionnaires_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--

ALTER SEQUENCE public.programs_questionnaires_id_seq OWNED BY public.programs_questionnaires.id;


--
-- Name: questionnaire_completenesses; Type: TABLE; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1264,6 +1285,13 @@ ALTER TABLE ONLY public.people_roles ALTER COLUMN id SET DEFAULT nextval('public
ALTER TABLE ONLY public.programs ALTER COLUMN id SET DEFAULT nextval('public.programs_id_seq'::regclass);


--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.programs_questionnaires ALTER COLUMN id SET DEFAULT nextval('public.programs_questionnaires_id_seq'::regclass);


--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1501,6 +1529,14 @@ ALTER TABLE ONLY public.programs
ADD CONSTRAINT programs_pkey PRIMARY KEY (id);


--
-- Name: programs_questionnaires_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.programs_questionnaires
ADD CONSTRAINT programs_questionnaires_pkey PRIMARY KEY (id);


--
-- Name: questionnaire_completenesses_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1736,6 +1772,13 @@ CREATE UNIQUE INDEX index_people_on_reset_password_token ON public.people USING
CREATE UNIQUE INDEX index_people_on_uid_and_provider ON public.people USING btree (uid, provider);


--
-- Name: index_programs_questionnaires_on_p_and_q; Type: INDEX; Schema: public; Owner: -
--

CREATE UNIQUE INDEX index_programs_questionnaires_on_p_and_q ON public.programs_questionnaires USING btree (program_id, questionnaire_id);


--
-- Name: index_study_applications_on_person_id; Type: INDEX; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1962,6 +2005,8 @@ INSERT INTO "schema_migrations" (version) VALUES
('20220717072150'),
('20220903054050'),
('20230222180223'),
('20230225063808');
('20230225063808'),
('20230226200547'),
('20230226201309');


5 changes: 0 additions & 5 deletions spec/models/program_spec.rb
Expand Up @@ -8,9 +8,4 @@
Then { is_expected.to validate_presence_of(:description_uk) }
Then { is_expected.to validate_presence_of(:description_ru) }
end

describe 'association' do
Then { is_expected.to have_many(:study_applications).dependent(:destroy) }
Then { is_expected.to have_and_belong_to_many(:questionnaires) }
end
end
7 changes: 0 additions & 7 deletions spec/models/questionnaire_spec.rb
@@ -1,13 +1,6 @@
require 'rails_helper'

describe Questionnaire do
describe 'association' do
Then { is_expected.to have_many(:questions).dependent(:destroy) }
Then { is_expected.to have_many(:questionnaire_completenesses).dependent(:destroy) }
Then { is_expected.to have_many(:people).through(:questionnaire_completenesses) }
Then { is_expected.to have_and_belong_to_many(:programs) }
end

describe 'validations' do
Then { is_expected.to validate_presence_of(:title_uk) }
Then { is_expected.to validate_presence_of(:title_ru) }
Expand Down

0 comments on commit 3e2b87d

Please sign in to comment.