Skip to content
This repository

[PT 46356017] integrate candidate with opening JD #41

Closed
wants to merge 1 commit into from

4 participants

Chunjie Nelson Lai Henry Chen EaseWay
Chunjie

assign/update 'opening jobs' to candidates

Limitation: currently only allow one 'opening jobs' to each candidate

Chunjie

add @Henry-CF to review

EaseWay

As we already used form_for, can we use f.select or f.collection_select etc. The raw select doesn't conform to usage of form_for

Nelson Lai
Owner
EaseWay

return is not necessary. $('select#departments_id') can be simplified by $('#departments_id') as id is referenced here. Omit 'event' if it is not used.

EaseWay

You don't need (function () { ... }).call(this); just use $(function () { });

EaseWay

The declaration line is not necessary, add "var" on the line that the variable is initialized.

EaseWay

In else, the transaction should be aborted.

EaseWay

rollback the transaction

EaseWay

rollback the transaction

Henry Chen Henry-CF commented on the diff
app/assets/javascripts/candidates.js
... ...
@@ -0,0 +1,16 @@
  1
+// Place all the behaviors and hooks related to the matching controller here.
  2
+// All this logic will automatically be available in application.js.
  3
+// You can also rename this file to openings.js.coffee, and only keep the coffee script
  4
+
  5
+(function() {
  6
+    $(function() {
  7
+        return $('select#departments_id').change(function(event) {
1
Henry Chen Collaborator
Henry-CF added a note

By convention, this should be department_ids.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/controllers/candidates_controller.rb
((6 lines not shown))
12 14
   end
13 15
 
14 16
   def edit
15 17
     @candidate = Candidate.find params[:id]
16  
-    @resume = File.basename(@candidate[:resume])
  18
+    @resume = File.basename(@candidate.resume)
  19
+    # NOTE: find_by_candidate_id => 'LIMIT 1', why ???
  20
+    @opening_candidates = @candidate.opening_candidates.where( :candidate_id => @candidate.id )
1
Henry Chen Collaborator
Henry-CF added a note

It's better to use @candidate.openings instead of @candidate.opening_candidates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/controllers/candidates_controller.rb
((27 lines not shown))
20 34
     upload_file(params[:candidate][:resume], params[:candidate][:name])
21 35
     params[:candidate][:resume] = upload_resume_file(params[:candidate][:name], params[:candidate][:resume].original_filename)
22 36
 
  37
+    params[:candidate].delete(:departments_id)
1
Henry Chen Collaborator
Henry-CF added a note

Similarly, this should be department_ids.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/controllers/candidates_controller.rb
((33 lines not shown))
23 40
     @candidate = Candidate.new params[:candidate]
24  
-    if @candidate.save
25  
-      redirect_to candidates_url, :notice => "Candidate \"#{@candidate.name}\" (#{@candidate.email}) was successfully created."
26  
-    else
27  
-      render :action => 'new'
  41
+    @opening_candidate = @candidate.opening_candidates.build(:opening_id => opening_id)
  42
+
  43
+    ActiveRecord::Base.transaction do
  44
+      if @candidate.save and @opening_candidate.save
1
Henry Chen Collaborator
Henry-CF added a note

By using candidate.openings, you can avoid the transaction code here, since @candidate.save will auto-update the joined table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/models/candidate.rb
@@ -4,4 +4,7 @@ class Candidate < ActiveRecord::Base
4 4
   validates :name, :presence => true
5 5
   validates :email, :presence => true
6 6
 
  7
+  has_many :opening_candidates, :class_name => "OpeningCandidate", :readonly => true
  8
+  has_many :opening, :class_name => "Opening", :through => :opening_candidates
1
Henry Chen Collaborator
Henry-CF added a note

should be 'openings' instead of 'opening'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/models/opening.rb
@@ -13,6 +13,9 @@ class Opening < ActiveRecord::Base
13 13
   has_many :opening_participants, :class_name => "OpeningParticipant", :readonly => true
14 14
   has_many :participants, :class_name => "User", :through => :opening_participants
15 15
 
  16
+  has_many :opening_candidates, :class_name => "OpeningCandidate", :readonly => true
1
Henry Chen Collaborator
Henry-CF added a note

'readonly => true' is not needed here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/models/candidate.rb
@@ -4,4 +4,7 @@ class Candidate < ActiveRecord::Base
4 4
   validates :name, :presence => true
5 5
   validates :email, :presence => true
6 6
 
  7
+  has_many :opening_candidates, :class_name => "OpeningCandidate", :readonly => true
1
Henry Chen Collaborator
Henry-CF added a note

'readonly => true' is not needed here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/views/candidates/_form.html.slim
@@ -38,6 +38,21 @@
38 38
           td
39 39
             = f.file_field :resume
40 40
   .control-group
  41
+    = f.label :opening, "Assign to this JD", :class => "control-label"
  42
+    .controls
  43
+      table
  44
+        tr
  45
+          td
  46
+            select id="departments_id" name="candidate[departments_id]"
  47
+              - @departments.each do |department|
  48
+                -if (not @assigned_departments.nil?) && @assigned_departments.size > 0 && @assigned_departments[0].id == department.id
1
Henry Chen Collaborator
Henry-CF added a note

It's better to define a helper function in CandidateHelpper to wrapper up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/views/candidates/_opening_select.slim
... ...
@@ -0,0 +1,18 @@
  1
+#openingid_select_wrapper
  2
+  -if not @department_id.nil?
  3
+    -department = Department.find(@department_id.to_i)
  4
+    -if department.nil?
  5
+      em Please select a department
  6
+    -else
  7
+      -openings = Opening.find_by_sql("SELECT * FROM openings WHERE department_id = #{@department_id.to_i}")
2
Henry Chen Collaborator
Henry-CF added a note

Don't use find_by_sql, please try find(:department_id => @department_id.to_i), or find(:department_id => @department_id) directly.

Nelson Lai Owner
wnellie added a note
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Henry Chen Henry-CF commented on the diff
app/views/candidates/_opening_select.slim
... ...
@@ -0,0 +1,18 @@
  1
+#openingid_select_wrapper
1
Henry Chen Collaborator
Henry-CF added a note

Maybe we need put this file into app/views/openings/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Chunjie

close this commit, refine code and then commit a new one

Chunjie Chunjie closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Mar 27, 2013
Chunjie [PT 46356017] integrate candidate with opening JD b6ddf09
This page is out of date. Refresh to see the latest.
16  app/assets/javascripts/candidates.js
... ...
@@ -0,0 +1,16 @@
  1
+// Place all the behaviors and hooks related to the matching controller here.
  2
+// All this logic will automatically be available in application.js.
  3
+// You can also rename this file to openings.js.coffee, and only keep the coffee script
  4
+
  5
+(function() {
  6
+    $(function() {
  7
+        return $('select#departments_id').change(function(event) {
  8
+            var department_id, select_wrapper, url;
  9
+            select_wrapper = $('#openingid_select_wrapper');
  10
+            $('select', select_wrapper).attr('disabled', true);
  11
+            department_id = $(this).val();
  12
+            url = "/positions/opening_options?department_id=" + department_id;
  13
+            return select_wrapper.load(url);
  14
+        });
  15
+    });
  16
+}).call(this);
67  app/controllers/candidates_controller.rb
@@ -9,37 +9,82 @@ def show
9 9
 
10 10
   def new
11 11
     @candidate = Candidate.new
  12
+    @departments = Department.all
  13
+    @department_id = @departments[0].id if @departments.size > 0
12 14
   end
13 15
 
14 16
   def edit
15 17
     @candidate = Candidate.find params[:id]
16  
-    @resume = File.basename(@candidate[:resume])
  18
+    @resume = File.basename(@candidate.resume)
  19
+    # NOTE: find_by_candidate_id => 'LIMIT 1', why ???
  20
+    @opening_candidates = @candidate.opening_candidates.where( :candidate_id => @candidate.id )
  21
+    # NOTE: Currently one candidate cannot be assigned to multiple opening jobs on web UI
  22
+    @assigned_departments = []
  23
+    if @opening_candidates.size > 0
  24
+      @opening_id = @opening_candidates[0].opening_id
  25
+      @assigned_departments = Department.joins(:openings).where( "openings.id = ?", @opening_id )
  26
+    end
  27
+    @departments = Department.all
  28
+    @department_id = @assigned_departments[0].id if @assigned_departments.size > 0
  29
+    @department_id ||= @departments[0].id if @departments.size > 0
17 30
   end
18 31
 
19 32
   def create
  33
+    # FIXME: how to handle error if exception between file io and database access?
20 34
     upload_file(params[:candidate][:resume], params[:candidate][:name])
21 35
     params[:candidate][:resume] = upload_resume_file(params[:candidate][:name], params[:candidate][:resume].original_filename)
22 36
 
  37
+    params[:candidate].delete(:departments_id)
  38
+    opening_id = params[:candidate].delete(:openings_id)
  39
+
23 40
     @candidate = Candidate.new params[:candidate]
24  
-    if @candidate.save
25  
-      redirect_to candidates_url, :notice => "Candidate \"#{@candidate.name}\" (#{@candidate.email}) was successfully created."
26  
-    else
27  
-      render :action => 'new'
  41
+    @opening_candidate = @candidate.opening_candidates.build(:opening_id => opening_id)
  42
+
  43
+    ActiveRecord::Base.transaction do
  44
+      if @candidate.save and @opening_candidate.save
  45
+        redirect_to candidates_url, :notice => "Candidate \"#{@candidate.name}\" (#{@candidate.email}) was successfully created."
  46
+      else
  47
+        render :action => 'new'
  48
+      end
28 49
     end
29 50
   end
30 51
 
31 52
   def update
32  
-    upload_file(params[:candidate][:resume], params[:candidate][:name])
33  
-    params[:candidate][:resume] = upload_resume_file(params[:candidate][:name], params[:candidate][:resume].original_filename)
  53
+    unless params[:candidate][:resume].nil?
  54
+      # FIXME: how to handle error if exception between file io and database access?
  55
+      upload_file(params[:candidate][:resume], params[:candidate][:name])
  56
+      params[:candidate][:resume] = upload_resume_file(params[:candidate][:name], params[:candidate][:resume].original_filename)
  57
+    end
  58
+
  59
+    params[:candidate].delete(:departments_id)
  60
+    # NOTE: Currently one candidate cannot be assigned to multiple opening jobs on web UI
  61
+    new_opening_id = params[:candidate].delete(:openings_id)
34 62
 
35 63
     @candidate = Candidate.find params[:id]
36  
-    if @candidate.update_attributes(params[:candidate])
37  
-      redirect_to candidates_url, :notice => "Candidate \"#{@candidate.name}\" (#{@candidate.email}) was successfully updated."
38  
-    else
39  
-      render :action => 'edit'
  64
+    # NOTE: find_by_candidate_id => 'LIMIT 1', why ???
  65
+    @opening_candidates = @candidate.opening_candidates.where( :candidate_id => @candidate.id )
  66
+    old_opening_id = nil
  67
+    old_opening_id = @opening_candidates[0].opening_id if @opening_candidates.size > 0
  68
+
  69
+    ActiveRecord::Base.transaction do
  70
+      if @candidate.update_attributes(params[:candidate])
  71
+        unless old_opening_id.nil?
  72
+          if not @candidate.opening_candidates.where(:opening_id => old_opening_id, :candidate_id => @candidate.id).update_all(:opening_id => new_opening_id)
  73
+            render :action => 'edit'
  74
+          end
  75
+        end
  76
+        redirect_to candidates_url, :notice => "Candidate \"#{@candidate.name}\" (#{@candidate.email}) was successfully updated."
  77
+      else
  78
+        render :action => 'edit'
  79
+      end
40 80
     end
41 81
   end
42 82
 
  83
+  def opening_options
  84
+    @department_id = params[:department_id]
  85
+    render :partial => 'opening_select'
  86
+  end
  87
+
43 88
   def resume
44 89
     @candidate = Candidate.find params[:id]
45 90
     download_file(@candidate[:resume])
3  app/models/candidate.rb
@@ -4,4 +4,7 @@ class Candidate < ActiveRecord::Base
4 4
   validates :name, :presence => true
5 5
   validates :email, :presence => true
6 6
 
  7
+  has_many :opening_candidates, :class_name => "OpeningCandidate", :readonly => true
  8
+  has_many :opening, :class_name => "Opening", :through => :opening_candidates
  9
+
7 10
 end
3  app/models/opening.rb
@@ -13,6 +13,9 @@ class Opening < ActiveRecord::Base
13 13
   has_many :opening_participants, :class_name => "OpeningParticipant", :readonly => true
14 14
   has_many :participants, :class_name => "User", :through => :opening_participants
15 15
 
  16
+  has_many :opening_candidates, :class_name => "OpeningCandidate", :readonly => true
  17
+  has_many :candidates, :class_name => "Candidate", :through => :opening_candidates
  18
+
16 19
   validates :title, :presence => true
17 20
 
18 21
 
8  app/models/opening_candidate.rb
... ...
@@ -0,0 +1,8 @@
  1
+class OpeningCandidate < ActiveRecord::Base
  2
+  attr_accessible :candidate_id, :opening_id
  3
+
  4
+  belongs_to :candidate, :foreign_key => :candidate_id, :readonly => true
  5
+  belongs_to :opening, :foreign_key => :opening_id, :readonly => true
  6
+
  7
+  validate :candidate_id, :opening_id, :presence => true
  8
+end
15  app/views/candidates/_form.html.slim
@@ -38,6 +38,21 @@
38 38
           td
39 39
             = f.file_field :resume
40 40
   .control-group
  41
+    = f.label :opening, "Assign to this JD", :class => "control-label"
  42
+    .controls
  43
+      table
  44
+        tr
  45
+          td
  46
+            select id="departments_id" name="candidate[departments_id]"
  47
+              - @departments.each do |department|
  48
+                -if (not @assigned_departments.nil?) && @assigned_departments.size > 0 && @assigned_departments[0].id == department.id
  49
+                  option selected=true value="#{department.id}" ="#{department.name}"
  50
+                -else
  51
+                  option value="#{department.id}" ="#{department.name}"
  52
+          td
  53
+          td
  54
+            = render partial: 'opening_select'
  55
+  .control-group
41 56
     .controls
42 57
       .actions
43 58
         = f.submit 'Save', :class => 'btn'
18  app/views/candidates/_opening_select.slim
... ...
@@ -0,0 +1,18 @@
  1
+#openingid_select_wrapper
  2
+  -if not @department_id.nil?
  3
+    -department = Department.find(@department_id.to_i)
  4
+    -if department.nil?
  5
+      em Please select a department
  6
+    -else
  7
+      -openings = Opening.find_by_sql("SELECT * FROM openings WHERE department_id = #{@department_id.to_i}")
  8
+      -if not openings.nil?
  9
+        select id="openings_id" name="candidate[openings_id]"
  10
+          -openings.each do |opening|
  11
+            -if (not @opening_id.nil?) && @opening_id == opening.id
  12
+              option selected=true value="#{opening.id}" ="#{opening.title}"
  13
+            -else
  14
+              option value="#{opening.id}" ="#{opening.title}"
  15
+      -else
  16
+        em Please file a new open position
  17
+  -else
  18
+    em Please select a department
1  config/routes.rb
@@ -23,6 +23,7 @@
23 23
   # Sample resource route (maps HTTP verbs to controller actions automatically):
24 24
   #   resources :products
25 25
   match '/addresses/subregion_options' => 'openings#subregion_options'
  26
+  match '/positions/opening_options' => 'candidates#opening_options'
26 27
 
27 28
   get "candidates/resume"
28 29
 
10  db/migrate/20130326033358_create_opening_candidates.rb
... ...
@@ -0,0 +1,10 @@
  1
+class CreateOpeningCandidates < ActiveRecord::Migration
  2
+  def change
  3
+    create_table :opening_candidates do |t|
  4
+      t.belongs_to :opening
  5
+      t.belongs_to :candidate
  6
+    end
  7
+    add_index :opening_candidates, :opening_id
  8
+    add_index :opening_candidates, :candidate_id
  9
+  end
  10
+end
10  db/schema.rb
@@ -11,7 +11,7 @@
11 11
 #
12 12
 # It's strongly recommended to check this file into your version control system.
13 13
 
14  
-ActiveRecord::Schema.define(:version => 20130325132846) do
  14
+ActiveRecord::Schema.define(:version => 20130326033358) do
15 15
 
16 16
   create_table "candidates", :force => true do |t|
17 17
     t.string   "name",        :null => false
@@ -49,6 +49,14 @@
49 49
     t.datetime "updated_at",   :null => false
50 50
   end
51 51
 
  52
+  create_table "opening_candidates", :force => true do |t|
  53
+    t.integer "opening_id"
  54
+    t.integer "candidate_id"
  55
+  end
  56
+
  57
+  add_index "opening_candidates", ["candidate_id"], :name => "index_opening_candidates_on_candidate_id"
  58
+  add_index "opening_candidates", ["opening_id"], :name => "index_opening_candidates_on_opening_id"
  59
+
52 60
   create_table "opening_participants", :id => false, :force => true do |t|
53 61
     t.integer "user_id"
54 62
     t.integer "opening_id"
5  spec/models/opening_candidate_spec.rb
... ...
@@ -0,0 +1,5 @@
  1
+require 'spec_helper'
  2
+
  3
+describe OpeningCandidate do
  4
+  pending "add some examples to (or delete) #{__FILE__}"
  5
+end
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.