diff --git a/app/controllers/user_skills_controller.rb b/app/controllers/user_skills_controller.rb new file mode 100644 index 0000000..95c25bd --- /dev/null +++ b/app/controllers/user_skills_controller.rb @@ -0,0 +1,62 @@ +class UserSkillsController < ApplicationController + before_action :set_user_skill, only: [:show, :update, :destroy] + + # GET /user_skills?user_id=:id + def index + @user_skills = UserSkill.where(user_id: params[:user_id]) + + render json: @user_skills + end + + # POST /user_skills + def create + @user_skill = UserSkill.new(user_skill_params) + + if @user_skill.save + render json: @user_skill, status: :created, location: @user_skill + else + render json: @user_skill.errors, status: :unprocessable_entity + end + end + + # PATCH/PUT /user_skills + def bulk_update + ApplicationRecord.transaction do + # Remove all existing skills for the user + UserSkill.where(user_id: params[:user_id]).destroy_all + + # Add the new list of user skills + params[:user_skills].each do |user_skill| + new_skill = UserSkill.new(user_skill.merge(user_id: params[:user_id])) + unless new_skill.save + raise ActiveRecord::Rollback + end + end + end + + # Render success or errors + if @user_skill.errors.empty? + render json: { message: "Skills updated successfully" } + else + render json: @user_skill.errors, status: :unprocessable_entity + end + end + + # DELETE /user_skills/:id + def destroy + @user_skill.destroy + head :no_content + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_user_skill + @user_skill = UserSkill.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def user_skill_params + params.require(:user_skill).permit(:last_applied_in_year, :level, :years_of_experience, :skill_id, :user_id) + end +end diff --git a/app/models/skill.rb b/app/models/skill.rb index 5065da1..d0b8448 100644 --- a/app/models/skill.rb +++ b/app/models/skill.rb @@ -9,9 +9,13 @@ # created_at :datetime not null # updated_at :datetime not null # +# Indexes +# +# index_skills_on_lower_name (lower((name)::text)) UNIQUE +# class Skill < ApplicationRecord has_many :user_skills, dependent: :destroy has_many :users, through: :user_skills - validates :name, presence: true + validates :name, presence: true, uniqueness: { case_sensitive: false } end diff --git a/config/routes.rb b/config/routes.rb index bf4cd36..be82200 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,4 +38,5 @@ resources :skills, only: [:index] resources :issues, only: [:index] resources :permissions, only: [:index] + resources :user_skills end diff --git a/db/migrate/20240923192947_add_unique_index_to_skills_name.rb b/db/migrate/20240923192947_add_unique_index_to_skills_name.rb new file mode 100644 index 0000000..79143ff --- /dev/null +++ b/db/migrate/20240923192947_add_unique_index_to_skills_name.rb @@ -0,0 +1,5 @@ +class AddUniqueIndexToSkillsName < ActiveRecord::Migration[7.0] + def change + add_index :skills, "LOWER(name)", unique: true, name: "index_skills_on_lower_name" + end +end diff --git a/db/schema.rb b/db/schema.rb index 4258758..0b69d0b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,8 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_06_13_164100) do +ActiveRecord::Schema[7.0].define(version: 2024_09_23_192947) do # These are extensions that must be enabled in order to support this database - enable_extension "pg_stat_statements" enable_extension "plpgsql" enable_extension "unaccent" @@ -230,6 +229,7 @@ t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index "lower((name)::text)", name: "index_skills_on_lower_name", unique: true end create_table "statement_of_work_financial_reports", force: :cascade do |t| diff --git a/spec/controllers/user_skills_controller_spec.rb b/spec/controllers/user_skills_controller_spec.rb new file mode 100644 index 0000000..724b75b --- /dev/null +++ b/spec/controllers/user_skills_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe UserSkillsController, type: :controller do + +end diff --git a/spec/factories/skills.rb b/spec/factories/skills.rb index a6e462d..7eda4fd 100644 --- a/spec/factories/skills.rb +++ b/spec/factories/skills.rb @@ -9,6 +9,10 @@ # created_at :datetime not null # updated_at :datetime not null # +# Indexes +# +# index_skills_on_lower_name (lower((name)::text)) UNIQUE +# FactoryBot.define do factory :skill do name { FFaker::Skill.tech_skill } diff --git a/spec/models/project_report_spec.rb b/spec/models/project_report_spec.rb index e6b659b..84b9187 100644 --- a/spec/models/project_report_spec.rb +++ b/spec/models/project_report_spec.rb @@ -2,7 +2,7 @@ # == Schema Information # -# Table name: project_auths +# Table name: project_reports # # id :bigint not null, primary key # key :string @@ -12,7 +12,7 @@ # # Indexes # -# index_project_auths_on_project_id (project_id) +# index_project_reports_on_project_id (project_id) # # Foreign Keys # diff --git a/spec/models/skill_spec.rb b/spec/models/skill_spec.rb index ff87fe2..34a612a 100644 --- a/spec/models/skill_spec.rb +++ b/spec/models/skill_spec.rb @@ -9,6 +9,10 @@ # created_at :datetime not null # updated_at :datetime not null # +# Indexes +# +# index_skills_on_lower_name (lower((name)::text)) UNIQUE +# require 'rails_helper' RSpec.describe Skill, type: :model do