diff --git a/app/controllers/job_applications_controller.rb b/app/controllers/job_applications_controller.rb
index 3e162bb..96ca3d9 100644
--- a/app/controllers/job_applications_controller.rb
+++ b/app/controllers/job_applications_controller.rb
@@ -96,18 +96,19 @@ def set_job_application
end
def job_application_params
- params.require(:job_application).permit(:date_applied, :company_name, :method_of_contact, :email_address, :point_of_contact, :website_link, :position_type, :position_title, :claimed_for_unemployment, :status)
+ params.require(:job_application).permit(:date_applied, :company_name, :method_of_contact, :email_address, :point_of_contact, :website_link, :position_type, :position_title, :claimed_for_unemployment, :status, :location)
end
def filter_and_sort_job_applications
job_applications = JobApplication.all
job_applications = job_applications.search(params[:search]) if params[:search].present?
+ job_applications = job_applications.by_location(params[:location]) if params[:location].present?
job_applications = job_applications.by_method_of_contact(params[:method_of_contact]) if params[:method_of_contact].present?
job_applications = job_applications.by_position_type(params[:position_type]) if params[:position_type].present?
+ job_applications = job_applications.by_status(params[:status]) if params[:status].present?
job_applications = job_applications.claimed_for_unemployment if params[:claimed_for_unemployment] == "true"
job_applications = job_applications.not_claimed_for_unemployment if params[:claimed_for_unemployment] == "false"
- job_applications = job_applications.by_status(params[:status]) if params[:status].present?
sort_column = sort_column(params[:sort])
sort_direction = sort_direction(params[:direction])
@@ -122,7 +123,7 @@ def filter_and_sort_job_applications
end
def sort_column(column)
- %w[date_applied company_name position_title created_at claimed_for_unemployment status].include?(column) ? column : "created_at"
+ %w[date_applied company_name position_title created_at claimed_for_unemployment location status].include?(column) ? column : "created_at"
end
def sort_direction(direction)
diff --git a/app/models/job_application.rb b/app/models/job_application.rb
index 3cefb91..a605515 100644
--- a/app/models/job_application.rb
+++ b/app/models/job_application.rb
@@ -1,5 +1,6 @@
class JobApplication < ApplicationRecord
attribute :status, :string
+ attribute :location, :string
validates :date_applied, :company_name, :method_of_contact, :position_type, :position_title, presence: true
validates :email_address, presence: true, if: -> { method_of_contact == "email" }
@@ -13,6 +14,7 @@ class JobApplication < ApplicationRecord
}
validates :claimed_for_unemployment, inclusion: {in: [true, false]}
validates :status, inclusion: {in: %w[hired interviewing job_offer no_response not_hired]}
+ validates :location, inclusion: {in: %w[hybrid in_office remote]}
enum method_of_contact: {
email: "email",
@@ -33,7 +35,13 @@ class JobApplication < ApplicationRecord
no_response: "no response",
not_hired: "not hired"
}
+ enum location: {
+ hybrid: "hybrid",
+ in_office: "in office",
+ remote: "remote"
+ }
+ scope :by_location, ->(location) { where(location: location) }
scope :by_method_of_contact, ->(method) { where(method_of_contact: method) }
scope :by_position_type, ->(type) { where(position_type: type) }
scope :by_status, ->(status) { where(status: status) }
@@ -45,6 +53,7 @@ class JobApplication < ApplicationRecord
email_address ILIKE :query OR
point_of_contact ILIKE :query OR
website_link ILIKE :query OR
+ location ILIKE :query OR
status ILIKE :query", query: "%#{query}%")
}
end
diff --git a/app/views/job_applications/_form.html.erb b/app/views/job_applications/_form.html.erb
index 6ad9f4f..d6e120a 100644
--- a/app/views/job_applications/_form.html.erb
+++ b/app/views/job_applications/_form.html.erb
@@ -52,13 +52,17 @@
<%= form.label :status, class: 'block text-sm font-medium text-gray-700 mb-2' %>
- <%= form.select :status, JobApplication.statuses.keys.map { |k| [k.humanize, k] }, { include_blank: 'Select a status' }, class: 'shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline' %>
-
- <%= form.label :claimed_for_unemployment, class: 'flex items-center' do %>
- <%= form.check_box :claimed_for_unemployment, class: 'h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded mr-2' %>
- Claimed for Unemployment
- <% end %>
-
+ <%= form.select :status, JobApplication.statuses.keys.map { |k| [k.humanize, k] }, { include_blank: false }, class: 'shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline' %>
+
+
+ <%= form.label :location, class: 'block text-sm font-medium text-gray-700 mb-2' %>
+ <%= form.select :location, JobApplication.locations.keys.map { |k| [k.humanize, k] }, { include_blank: false }, class: 'shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline' %>
+
+
+ <%= form.label :claimed_for_unemployment, class: 'flex items-center' do %>
+ <%= form.check_box :claimed_for_unemployment, class: 'h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded mr-2' %>
+ Claimed for Unemployment
+ <% end %>
diff --git a/app/views/job_applications/_job_application.html.erb b/app/views/job_applications/_job_application.html.erb
index 5d868c6..0c39849 100644
--- a/app/views/job_applications/_job_application.html.erb
+++ b/app/views/job_applications/_job_application.html.erb
@@ -26,6 +26,9 @@
<%= job_application.status.humanize %>
|
+
+ <%= job_application.location.humanize %>
+ |
<% if job_application.website_link.present? %>
<%= link_to 'Visit',
diff --git a/app/views/job_applications/_job_applications_table.html.erb b/app/views/job_applications/_job_applications_table.html.erb
index 8369af1..293f1ef 100644
--- a/app/views/job_applications/_job_applications_table.html.erb
+++ b/app/views/job_applications/_job_applications_table.html.erb
@@ -31,6 +31,9 @@
|
<%= sort_link_to 'Status', 'status' %>
|
+
+ <%= sort_link_to 'Location', 'location' %>
+ |
Website
|
diff --git a/db/migrate/20240718143013_add_location_to_job_applications.rb b/db/migrate/20240718143013_add_location_to_job_applications.rb
new file mode 100644
index 0000000..c9918da
--- /dev/null
+++ b/db/migrate/20240718143013_add_location_to_job_applications.rb
@@ -0,0 +1,6 @@
+class AddLocationToJobApplications < ActiveRecord::Migration[7.1]
+ def change
+ add_column :job_applications, :location, :string, null: false, default: "remote"
+ add_check_constraint :job_applications, "location IN ('remote', 'in office', 'hybrid')", name: "check_valid_location"
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 8d1df02..b8dc100 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.1].define(version: 2024_07_17_175130) do
+ActiveRecord::Schema[7.1].define(version: 2024_07_18_143013) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -28,6 +28,8 @@
t.datetime "updated_at", null: false
t.boolean "claimed_for_unemployment", default: false, null: false
t.string "status", default: "no response", null: false
+ t.string "location", default: "remote", null: false
+ t.check_constraint "location::text = ANY (ARRAY['remote'::character varying, 'in office'::character varying, 'hybrid'::character varying]::text[])", name: "check_valid_location"
t.check_constraint "status::text = ANY (ARRAY['interviewing'::character varying, 'no response'::character varying, 'hired'::character varying, 'not hired'::character varying, 'job offer'::character varying]::text[])", name: "check_valid_status"
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 728f7af..e02cdb9 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1,7 +1,7 @@
require "faker"
JobApplication.destroy_all
-50.times do
+20.times do
method_of_contact = %w[email internet_job_application recruiter].sample
email_address = (method_of_contact == "email") ? Faker::Internet.email : nil
website_link = (method_of_contact == "internet_job_application") ? "https://example.com/" : nil
@@ -16,6 +16,7 @@
position_title: Faker::Job.title,
website_link: website_link,
claimed_for_unemployment: [true, false].sample,
- status: %w[interviewing no_response not_hired job_offer].sample
+ status: %w[interviewing no_response not_hired job_offer].sample,
+ location: %w[remote in_office hybrid].sample
)
end
diff --git a/test/factories/job_applications_factory.rb b/test/factories/job_applications_factory.rb
index c08ad97..2bca962 100644
--- a/test/factories/job_applications_factory.rb
+++ b/test/factories/job_applications_factory.rb
@@ -1,14 +1,15 @@
FactoryBot.define do
factory :job_application do
- date_applied { Date.new(2023, 1, 1) }
+ claimed_for_unemployment { false }
company_name { "Example Company" }
+ date_applied { Date.new(2023, 1, 1) }
+ email_address { "example@example.com" }
+ location { "remote" }
method_of_contact { "email" }
- position_type { "full_time" }
+ point_of_contact { "John Doe" }
position_title { "Software Engineer" }
- claimed_for_unemployment { false }
+ position_type { "full_time" }
status { "interviewing" }
- email_address { "example@example.com" }
- point_of_contact { "John Doe" }
trait :with_website do
method_of_contact { "internet_job_application" }
diff --git a/test/models/job_application_test.rb b/test/models/job_application_test.rb
index ab59240..4f7e6a5 100644
--- a/test/models/job_application_test.rb
+++ b/test/models/job_application_test.rb
@@ -60,6 +60,12 @@ def setup
assert_not_nil @job_application.errors[:website_link]
end
+ test "job application validates location inclusion" do
+ assert_raises(ArgumentError) do
+ build(:job_application, location: "invalid_location")
+ end
+ end
+
test "job application validates status inclusion" do
assert_raises(ArgumentError) do
build(:job_application, status: "invalid_status")
@@ -84,6 +90,15 @@ def setup
assert_equal 1, JobApplication.by_method_of_contact("internet_job_application").count
end
+ test "by_location scope finds job applications by location" do
+ JobApplication.destroy_all
+ create(:job_application, location: "remote")
+ create(:job_application, location: "in_office")
+
+ assert_equal 1, JobApplication.by_location("remote").count
+ assert_equal 1, JobApplication.by_location("in_office").count
+ end
+
test "by_position_type scope finds job applications by position_type" do
JobApplication.destroy_all
create(:job_application, position_type: "full_time")