Skip to content

Commit

Permalink
introduce Ilikable concern to make it reusable and sanitized
Browse files Browse the repository at this point in the history
  • Loading branch information
mpugach committed Sep 14, 2022
1 parent d9cf572 commit f431c1d
Show file tree
Hide file tree
Showing 16 changed files with 35 additions and 29 deletions.
4 changes: 1 addition & 3 deletions app/interactions/ui/academic_groups_loading_interaction.rb
Expand Up @@ -3,12 +3,10 @@ class AcademicGroupsLoadingInteraction < BaseInteraction
include IdAndTitleLoadable

def init
# TODO: replace this when ElasticSearch appears
@json_root = :academic_groups
@resource = AcademicGroup
.where(graduated_at: nil)
.where('title ILIKE ?', "%#{params[:q]}%")
# TODO: injection is possible!
.ilike('title', params[:q])
end
end
end
4 changes: 1 addition & 3 deletions app/interactions/ui/classrooms_loading_interaction.rb
Expand Up @@ -3,10 +3,8 @@ class ClassroomsLoadingInteraction < BaseInteraction
include IdAndTitleLoadable

def init
# TODO: replace this when ElasticSearch appears
@json_root = :classrooms
@resource = Classroom.where('title ILIKE ?', "%#{params[:q]}%")
# TODO: injection is possible!
@resource = Classroom.ilike('title', params[:q])
end
end
end
4 changes: 1 addition & 3 deletions app/interactions/ui/courses_loading_interaction.rb
Expand Up @@ -3,10 +3,8 @@ class CoursesLoadingInteraction < BaseInteraction
include IdAndTitleLoadable

def init
# TODO: replace this when ElasticSearch appears
@json_root = :courses
@resource = Course.where('title ILIKE ?', "%#{params[:q]}%")
# TODO: injection is possible!
@resource = Course.ilike('title', params[:q])
end

def serialize_resource(course)
Expand Down
4 changes: 1 addition & 3 deletions app/interactions/ui/group_admins_loading_interaction.rb
Expand Up @@ -3,9 +3,7 @@ class GroupAdminsLoadingInteraction < BaseInteraction
include Peoplable

def init
# TODO: replace this when ElasticSearch appears
@people = Person.where('complex_name ILIKE ?', "%#{params[:q]}%")
# TODO: injection is possible!
@people = Person.ilike('complex_name', params[:q])
end
end
end
4 changes: 1 addition & 3 deletions app/interactions/ui/group_curators_loading_interaction.rb
Expand Up @@ -3,9 +3,7 @@ class GroupCuratorsLoadingInteraction < BaseInteraction
include Peoplable

def init
# TODO: replace this when ElasticSearch appears
@people = Person.joins(:teacher_profile).where('complex_name ILIKE ?', "%#{params[:q]}%")
# TODO: injection is possible!
@people = Person.joins(:teacher_profile).ilike('complex_name', params[:q])
end
end
end
4 changes: 1 addition & 3 deletions app/interactions/ui/group_praepostors_loading_interaction.rb
Expand Up @@ -3,9 +3,7 @@ class GroupPraepostorsLoadingInteraction < BaseInteraction
include Peoplable

def init
# TODO: replace this when ElasticSearch appears
@people = AcademicGroup.find(params[:group_id]).active_students.where('complex_name ILIKE ?', "%#{params[:q]}%")
# TODO: injection is possible!
@people = AcademicGroup.find(params[:group_id]).active_students.ilike('complex_name', params[:q])
end
end
end
3 changes: 1 addition & 2 deletions app/interactions/ui/teacher_profiles_loading_interaction.rb
@@ -1,11 +1,10 @@
module Ui
class TeacherProfilesLoadingInteraction < BaseInteraction
def init
# TODO: replace this when ElasticSearch appears
@teacher_profiles = TeacherProfile
.includes(:person)
.joins(:person)
.where('people.complex_name ILIKE ?', "%#{params[:q]}%") # TODO: injection is possible!
.ilike('people.complex_name', params[:q])
end

def serialize_profile(profile)
Expand Down
2 changes: 2 additions & 0 deletions app/models/academic_group.rb
@@ -1,4 +1,6 @@
class AcademicGroup < ApplicationRecord
include Ilikable

has_many :group_participations, dependent: :destroy
has_many :student_profiles, through: :group_participations

Expand Down
2 changes: 2 additions & 0 deletions app/models/classroom.rb
@@ -1,4 +1,6 @@
class Classroom < ApplicationRecord
include Ilikable

has_many :class_schedules, dependent: :destroy

validates :title, presence: true
Expand Down
9 changes: 9 additions & 0 deletions app/models/concerns/ilikable.rb
@@ -0,0 +1,9 @@
module Ilikable
extend ActiveSupport::Concern

class_methods do
def ilike(field, query)
where("#{field} ILIKE ?", "%#{sanitize_sql_like(query || '')}%")
end
end
end
2 changes: 2 additions & 0 deletions app/models/course.rb
@@ -1,4 +1,6 @@
class Course < ApplicationRecord
include Ilikable

has_many :class_schedules, dependent: :destroy
has_many :teacher_specialities, dependent: :destroy
has_many :teacher_profiles, through: :teacher_specialities
Expand Down
2 changes: 2 additions & 0 deletions app/models/person.rb
@@ -1,4 +1,6 @@
class Person < ApplicationRecord
include Ilikable

# TODO: use enums here since we run rails 4.1
MARITAL_STATUSES = %i[single in_relationship married divorced widowed].freeze

Expand Down
2 changes: 2 additions & 0 deletions app/models/teacher_profile.rb
@@ -1,4 +1,6 @@
class TeacherProfile < ApplicationRecord
include Ilikable

belongs_to :person
has_many :teacher_specialities, dependent: :destroy
has_many :class_schedules, dependent: :destroy
Expand Down
8 changes: 4 additions & 4 deletions app/views/academic_groups/_form.html.haml
Expand Up @@ -9,12 +9,12 @@
= f.input :establ_date
= f.input :group_description
= f.association :curator, label_method: :complex_name, collection: [f.object.curator].compact,
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/group_curators' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_group_curators_path } }
= f.association :administrator, label_method: :complex_name, collection: [f.object.administrator].compact,
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/group_admins' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_group_admins_path } }
= f.association :praepostor, label_method: :complex_name, collection: [f.object.praepostor].compact,
input_html: { data: { :placeholder => 'Select an option',
:'ajax--url' => "/ui/group_praepostors?group_id=#{f.object.id}" },
input_html: { data: { placeholder: 'Select an option',
'ajax--url': ui_group_praepostors_path(group_id: f.object.id) },
disabled: !f.object.persisted? }
= f.input :message_ru
= f.input :message_uk
Expand Down
8 changes: 4 additions & 4 deletions app/views/class_schedules/_form.html.haml
Expand Up @@ -7,14 +7,14 @@
= render 'shared/error_messages', object: f.object

= f.association :course, label_method: :label_for_select, collection: [*f.object.course],
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/courses' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_courses_path } }
= f.input :subject
= f.association :classroom, label_method: :title, collection: [*f.object.classroom],
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/classrooms' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_classrooms_path } }
= f.association :teacher_profile, label_method: :complex_name, collection: [*f.object.teacher_profile],
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/teacher_profiles' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_teacher_profiles_path } }
= f.association :academic_groups, label_method: :title, collection: f.object.academic_groups,
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/academic_groups' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_academic_groups_path } }

.row
.col-xs-12.col-sm-6
Expand Down
2 changes: 1 addition & 1 deletion app/views/courses/_form.html.haml
Expand Up @@ -10,6 +10,6 @@
= f.input :description
= f.input :variant
= f.association :teacher_profiles, label_method: :complex_name, collection: f.object.teacher_profiles,
input_html: { data: { :placeholder => 'Select an option', :'ajax--url' => '/ui/teacher_profiles' } }
input_html: { data: { placeholder: 'Select an option', 'ajax--url': ui_teacher_profiles_path } }

= f.button :submit

0 comments on commit f431c1d

Please sign in to comment.