Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/controllers/job_applications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions app/models/job_application.rb
Original file line number Diff line number Diff line change
@@ -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" }
Expand All @@ -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",
Expand All @@ -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) }
Expand All @@ -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
18 changes: 11 additions & 7 deletions app/views/job_applications/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@
</div>
<div>
<%= 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' %>
<div class="mt-8">
<%= 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' %>
<span class="text-sm font-medium text-gray-700">Claimed for Unemployment</span>
<% end %>
</div>
<%= 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' %>
</div>
<div>
<%= 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' %>
</div>
<div class="mt-8">
<%= 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' %>
<span class="text-sm font-medium text-gray-700">Claimed for Unemployment</span>
<% end %>
</div>
</div>
<div class="flex items-center justify-end mt-6">
Expand Down
3 changes: 3 additions & 0 deletions app/views/job_applications/_job_application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<%= job_application.status.humanize %>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<%= job_application.location.humanize %>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
<% if job_application.website_link.present? %>
<%= link_to 'Visit',
Expand Down
3 changes: 3 additions & 0 deletions app/views/job_applications/_job_applications_table.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<th class="px-5 py-3">
<%= sort_link_to 'Status', 'status' %>
</th>
<th class="px-5 py-3">
<%= sort_link_to 'Location', 'location' %>
</th>
<th class="px-5 py-3">
Website
</th>
Expand Down
6 changes: 6 additions & 0 deletions db/migrate/20240718143013_add_location_to_job_applications.rb
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
11 changes: 6 additions & 5 deletions test/factories/job_applications_factory.rb
Original file line number Diff line number Diff line change
@@ -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 { "[email protected]" }
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 { "[email protected]" }
point_of_contact { "John Doe" }

trait :with_website do
method_of_contact { "internet_job_application" }
Expand Down
15 changes: 15 additions & 0 deletions test/models/job_application_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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")
Expand Down