Commit 99779d23 by Ngô Trung Hưng

create func search & auto index data to solr server

parent ef3031b4
Pipeline #1038 canceled with stages
in 0 seconds
{
"compile-hero.disable-compile-files-on-did-save-code": true
}
\ No newline at end of file
...@@ -35,6 +35,7 @@ gem 'devise' ...@@ -35,6 +35,7 @@ gem 'devise'
gem 'carrierwave' gem 'carrierwave'
gem 'rails-i18n' gem 'rails-i18n'
gem 'i18n-js' gem 'i18n-js'
gem 'rsolr'
# Use ActiveStorage variant # Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8' # gem 'mini_magick', '~> 4.8'
...@@ -47,6 +48,7 @@ gem 'bootsnap', '>= 1.1.0', require: false ...@@ -47,6 +48,7 @@ gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console # Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rubocop'
gem 'dotenv-rails' gem 'dotenv-rails'
gem 'pry' gem 'pry'
end end
......
...@@ -51,6 +51,7 @@ GEM ...@@ -51,6 +51,7 @@ GEM
archive-zip (0.12.0) archive-zip (0.12.0)
io-like (~> 0.3.0) io-like (~> 0.3.0)
arel (9.0.0) arel (9.0.0)
ast (2.4.1)
bcrypt (3.1.15) bcrypt (3.1.15)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.4.7) bootsnap (1.4.7)
...@@ -107,6 +108,8 @@ GEM ...@@ -107,6 +108,8 @@ GEM
request_store (>= 1.0) request_store (>= 1.0)
erubi (1.9.0) erubi (1.9.0)
execjs (2.7.0) execjs (2.7.0)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
ffi (1.13.1) ffi (1.13.1)
globalid (0.4.2) globalid (0.4.2)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
...@@ -150,11 +153,15 @@ GEM ...@@ -150,11 +153,15 @@ GEM
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.14.1) minitest (5.14.1)
msgpack (1.3.3) msgpack (1.3.3)
multipart-post (2.1.1)
mysql2 (0.5.3) mysql2 (0.5.3)
nio4r (2.5.2) nio4r (2.5.2)
nokogiri (1.10.10) nokogiri (1.10.10)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
orm_adapter (0.5.0) orm_adapter (0.5.0)
parallel (1.19.2)
parser (2.7.1.4)
ast (~> 2.4.1)
pry (0.13.1) pry (0.13.1)
coderay (~> 1.1) coderay (~> 1.1)
method_source (~> 1.0) method_source (~> 1.0)
...@@ -190,6 +197,7 @@ GEM ...@@ -190,6 +197,7 @@ GEM
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0) thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (13.0.1) rake (13.0.1)
rb-fsevent (0.10.4) rb-fsevent (0.10.4)
rb-inotify (0.10.1) rb-inotify (0.10.1)
...@@ -200,6 +208,22 @@ GEM ...@@ -200,6 +208,22 @@ GEM
responders (3.0.1) responders (3.0.1)
actionpack (>= 5.0) actionpack (>= 5.0)
railties (>= 5.0) railties (>= 5.0)
rexml (3.2.4)
rsolr (2.3.0)
builder (>= 2.1.2)
faraday (>= 0.9.0)
rubocop (0.89.1)
parallel (~> 1.10)
parser (>= 2.7.1.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.3.0, < 1.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.3.0)
parser (>= 2.7.1.4)
ruby-progressbar (1.10.1)
ruby-vips (2.0.17) ruby-vips (2.0.17)
ffi (~> 1.9) ffi (~> 1.9)
ruby_dep (1.5.0) ruby_dep (1.5.0)
...@@ -239,6 +263,7 @@ GEM ...@@ -239,6 +263,7 @@ GEM
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (4.2.0) uglifier (4.2.0)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
unicode-display_width (1.7.0)
warden (1.2.8) warden (1.2.8)
rack (>= 2.0.6) rack (>= 2.0.6)
web-console (3.7.0) web-console (3.7.0)
...@@ -278,6 +303,8 @@ DEPENDENCIES ...@@ -278,6 +303,8 @@ DEPENDENCIES
puma (~> 3.11) puma (~> 3.11)
rails (~> 5.2.4, >= 5.2.4.3) rails (~> 5.2.4, >= 5.2.4.3)
rails-i18n rails-i18n
rsolr
rubocop
sass-rails (~> 5.0) sass-rails (~> 5.0)
selenium-webdriver selenium-webdriver
spring spring
......
...@@ -5,6 +5,6 @@ class HistoriesController < ApplicationController ...@@ -5,6 +5,6 @@ class HistoriesController < ApplicationController
def index def index
histories = current_user.histories.order(created_at: :desc) histories = current_user.histories.order(created_at: :desc)
@jobs = histories.map(&:job) @jobs = histories.map(&:job).select { |val| val.present? }
end end
end end
# frozen_string_literal: true
class PasswordsController < Devise::PasswordsController
def new
super
end
def create
self.resource = resource_class.send_reset_password_instructions(resource_params)
yield resource if block_given?
if successfully_sent?(resource)
respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name))
else
helpers.render_errors(resource)
respond_with(resource) { |format| format.html { redirect_to new_password_path(resource) } }
end
end
end
class SearchController < ApplicationController
NUMBER_RECORD_IN_PAGE = 10
before_action :load_data_dropdown, only: :multi_search
def multi_search
solr = connect_solr
@keyword = params[:keyword]
@industry = Industry.find_by(id: params[:industry]) if params[:industry].present?
@city = City.find_by(id: params[:city]) if params[:city].present?
# Value data is Array, index[0]: name_job or company name, index[1]: id industry, index[2]: id location
data = sub_space_params!(params[:keyword], params[:industry], params[:city])
query = if params[:keyword].blank? && params[:industry].blank? && params[:city].blank?
'*:*'
else
"solr((name: #{data[0]}) OR (company_name: #{data[0]})) AND (industry_id: #{data[1]}) AND (location_id: #{data[2]})"
end
response = solr.paginate(params[:page], NUMBER_RECORD_IN_PAGE, 'select', params: { q: query })
@results = Kaminari.paginate_array(response['response']['docs'], total_count: response['response']['numFound']).page(params[:page]).per(NUMBER_RECORD_IN_PAGE)
return render 'error/page_not_found' if params[:page].to_i > @results.total_pages
render :result
end
def sub_space_params!(keyword, industry_id, location_id)
arr_params = []
keyword = keyword.present? ? Regexp.escape(keyword) : ''
industry_id = industry_id.present? ? Regexp.escape(industry_id) : ''
location_id = location_id.present? ? Regexp.escape(location_id) : ''
arr_params << keyword << industry_id << location_id
arr_params.each { |val| val.sub!('', '*') if val.blank? }
end
def load_data_dropdown
@industries = Industry.order(name: :asc).all
@cities = City.select(:id, :name)
end
private
def connect_solr
SolrSetting::SolrServer.connection
end
end
module SearchHelper
end
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Process search pc--> <!-- Process search pc-->
<div class="box-search"> <div class="box-search">
<div class="search_scaffold"> <div class="search_scaffold">
...@@ -23,29 +22,30 @@ ...@@ -23,29 +22,30 @@
<h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %></h4> <h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %></h4>
<% end %> <% end %>
</div> </div>
<%= form_with url: search_path, method: :get, local: true, skip_enforcing_utf8: true do |f| %>
<div class="filter_box"> <div class="filter_box">
<div class="search_input"> <div class="search_input">
<input type="search" name="" id="" class="custom_input_search" placeholder="<%= t('pages.banner.search_placeholder') %>"> <%= f.search_field :keyword, value: @keyword, class: 'custom_input_search', placeholder: t('pages.banner.search_placeholder') %>
</div> </div>
<div class="search_industries"> <div class="search_industries">
<div class="icon_list"> <div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i> <i class="fa fa-list-ul" aria-hidden="true"></i>
</div> </div>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %> <% selected = @industry.blank? ? '*' : @industry.id %>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name', selected), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div> </div>
<div class="search_location"> <div class="search_location">
<div class="icon_list"> <div class="icon_list">
<i class="fas fa-map-marker-alt"></i> <i class="fas fa-map-marker-alt"></i>
</div> </div>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %> <% selected = @city.blank? ? '*' : @city.id %>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name', selected), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div> </div>
<div class="search_submit"> <div class="search_submit">
<button type="submit" class="btn_search_submit"> <%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
<i class="fas fa-search"></i>
<%= t('pages.banner.btn_text_search') %>
</button>
</div> </div>
</div> </div>
<% end %>
</div> </div>
</div> </div>
<!-- Process search tablet--> <!-- Process search tablet-->
...@@ -54,29 +54,30 @@ ...@@ -54,29 +54,30 @@
<div class = "total_job"> <div class = "total_job">
<h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %> </h4> <h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %> </h4>
</div> </div>
<%= form_with url: search_path, method: :get, local: true, skip_enforcing_utf8: true do |f| %>
<div class="filter_box filter_box_tablet"> <div class="filter_box filter_box_tablet">
<div class="search_input"> <div class="search_input">
<input type="search" name="" id="" class="custom_input_search" placeholder="<%= t('pages.banner.search_placeholder') %>"> <%= f.search_field :keyword, value: @keyword, class: 'custom_input_search', placeholder: t('pages.banner.search_placeholder') %>
</div> </div>
<div class="search_industries"> <div class="search_industries">
<div class="icon_list"> <div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i> <i class="fa fa-list-ul" aria-hidden="true"></i>
</div> </div>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %> <% selected = @industry.blank? ? '*' : @industry.id %>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name', selected), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div> </div>
<div class="search_location"> <div class="search_location">
<div class="icon_list"> <div class="icon_list">
<i class="fas fa-map-marker-alt"></i> <i class="fas fa-map-marker-alt"></i>
</div> </div>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %> <% selected = @city.blank? ? '*' : @city.id %>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name', selected), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div> </div>
<div class="search_submit"> <div class="search_submit">
<button type="submit" class="btn_search_submit"> <%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
<i class="fas fa-search"></i>
<%= t('pages.banner.btn_text_search') %>
</button>
</div> </div>
</div> </div>
<% end %>
</div> </div>
</div> </div>
<div class="box-show-total-jobs-mobile"> <div class="box-show-total-jobs-mobile">
...@@ -84,20 +85,23 @@ ...@@ -84,20 +85,23 @@
</div> </div>
<!-- Process search mobile--> <!-- Process search mobile-->
<div class="box-search-mobile"> <div class="box-search-mobile">
<%= form_with url: search_path, method: :get, local: true, skip_enforcing_utf8: true do |f| %>
<div class="fillter-search-mobile"> <div class="fillter-search-mobile">
<div class="container"> <div class="container">
<div class="row no-gutters"> <div class="row no-gutters">
<div class="col-md-12"> <div class="col-md-12">
<input type="search" name="" id="" class="custom_input_mobile_search" placeholder="<%= t('pages.banner.search_placeholder') %>"> <%= f.search_field :keyword, value: @keyword, class: 'custom_input_mobile_search', placeholder: t('pages.banner.search_placeholder') %>
</div> </div>
<div class="col-sm-6 col-xs-12"> <div class="col-sm-6 col-xs-12">
<div class="search_industries_mobile"> <div class="search_industries_mobile">
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries_mobile' %> <% selected = @industry.blank? ? '*' : @industry.id %>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name', selected), prompt: t('pages.banner.all_industries'), class: 'show_list_industries_mobile' %>
</div> </div>
</div> </div>
<div class="col-sm-6 col-xs-12"> <div class="col-sm-6 col-xs-12">
<div class="search_location_mobile"> <div class="search_location_mobile">
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities_mobile' %> <% selected = @city.blank? ? '*' : @city.id %>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name', selected), prompt: t('pages.banner.all_locations'), class: 'show_list_cities_mobile' %>
</div> </div>
</div> </div>
</div> </div>
...@@ -106,12 +110,10 @@ ...@@ -106,12 +110,10 @@
<div class="container"> <div class="container">
<div class="row no-gutters"> <div class="row no-gutters">
<div class="col-sm-12"> <div class="col-sm-12">
<button type="submit" class="btn_search_submit"> <%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
<i class="fas fa-search"></i>
<%= t('pages.banner.btn_text_search') %>
</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<% end %>
</div> </div>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="box_jobs">
<div class="col-sm-12 d-block d-sm-none">
<div class="link_favorite_top block_link_favorite md">
<% if user_signed_in? %>
<% favorite_id = current_user.favorites.find_by(job_id: data['id']) %>
<% if favorite_id.present? %>
<%= render 'job/link_destroy', favorite_id: favorite_id %>
<% else %>
<%= render 'job/link_create', job_id: data['id'] %>
<% end %>
<% else %>
<span class="link_favorite span_click_favorite"><i class="far fa-heart"></i></span>
<% end %>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-md-9 col-lg-10">
<div class="box_info">
<div class="lol">
<%= link_to data['name'], detail_job_path(id: data['id']), class: 'job_name' %>
</div>
<div class="cop">
<h5 class="box_info_copany_name"><i class="far fa-building"></i> <%= data['company_name'] %></h5>
</div>
<div class="loc">
<h5 class="box_info_location"><i class="fas fa-map-marker-alt"></i>
<%= data['locations'].join(' | ') %>
</h5>
</div>
<h5 class="box_info_salary"><i class="fas fa-dollar-sign"></i>&nbsp;<%= "#{t('pages.index.salary')}: #{data['salary']}" %></h5>
<div class="coc">
<h5 class="box_info_des"><%= strip_tags(data['description']) %></h5>
</div>
</div>
</div>
<div class="col-sm-2 col-md-3 d-none d-sm-block col-lg-2">
<div class="link_favorite_top block_link_favorite">
<% if user_signed_in? %>
<% favorite_id = current_user.favorites.find_by(job_id: data['id']) %>
<% if favorite_id.present? %>
<%= render 'job/link_destroy', favorite_id: favorite_id %>
<% else %>
<%= render 'job/link_create', job_id: data['id'] %>
<% end %>
<% else %>
<span class="link_favorite span_click_favorite"><i class="far fa-heart"></i></span>
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<% provide(:title ,"#{t('pages.detail.br_title')}") %>
<%= render 'home/banner_and_search' %>
<div class="padding_index"></div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="breadcrumb_total_search">
<span class="breadcrumb-item active">
<% if @results.total_count == Job.count %>
<div style="word-wrap: break-word;">
<%= "#{t('pages.result.all')} #{@results.total_count}" %>
</div>
<% elsif @results.total_count > 0 %>
<%= t('pages.result.result_find', job: @results.total_count, key: @keyword).html_safe %>
<% else %>
<%= t('pages.result.no_result_find', key: @keyword).html_safe %>
<% end %>
<b><%= "#{@industry.try(:name)} #{@city.try(:name)}" %></b>
</span>
</div>
</div>
<div class="col-lg-12">
<div class="breadcrumb_total_search_pagination_jobs">
<div class="pagination_jobs">
<div id="paginator">
<%= paginate @results %>
</div>
</div>
</div>
</div>
</div>
</div>
<%= render 'job/modal_login' %>
<%= render partial: 'block_info_job', collection: @results, as: :data %>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="breadcrumb_total_search_pagination_jobs">
<div class="pagination_jobs">
<div class="paginator">
<%= paginate @results %>
</div>
</div>
</div>
</div>
</div>
</div>
<%= render 'shared/scroll_top' %>
...@@ -14,6 +14,7 @@ module Venjob ...@@ -14,6 +14,7 @@ module Venjob
config.autoload_paths << Rails.root.join('lib/service') config.autoload_paths << Rails.root.join('lib/service')
config.autoload_paths << Rails.root.join('lib/src') config.autoload_paths << Rails.root.join('lib/src')
config.eager_load_paths << Rails.root.join('lib/business') config.eager_load_paths << Rails.root.join('lib/business')
config.eager_load_paths << Rails.root.join('lib/solr')
# i18n # i18n
config.i18n.available_locales = [:en, :vi] config.i18n.available_locales = [:en, :vi]
config.i18n.default_locale = :vi config.i18n.default_locale = :vi
......
...@@ -14,19 +14,19 @@ default: &default ...@@ -14,19 +14,19 @@ default: &default
encoding: utf8mb4 encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root username: root
password: '1' password: 'Trunghung5055@'
socket: /var/run/mysqld/mysqld.sock socket: /var/run/mysqld/mysqld.sock
development: development:
<<: *default <<: *default
database: venjob_development database: hungnt_development
# Warning: The database defined as "test" will be erased and # Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake". # re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production. # Do not set this db to the same as development or production.
test: test:
<<: *default <<: *default
database: venjob_test database: hungnt_test
# As with config/secrets.yml, you never want to store sensitive information, # As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is # like your database password, in your source code. If your source code is
......
...@@ -22,7 +22,7 @@ Rails.application.configure do ...@@ -22,7 +22,7 @@ Rails.application.configure do
config.eager_load = false config.eager_load = false
# Show full error reports. # Show full error reports.
config.consider_all_requests_local = false config.consider_all_requests_local = true
# Enable/disable caching. By default caching is disabled. # Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching. # Run rails dev:cache to toggle caching.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Kaminari.configure do |config| Kaminari.configure do |config|
config.default_per_page = 20 config.default_per_page = 20
# config.max_per_page = nil # config.max_per_page = nil
config.window = 3 config.window = 2
# config.outer_window = 0 # config.outer_window = 0
# config.left = 0 # config.left = 0
# config.right = 0 # config.right = 0
......
...@@ -33,15 +33,16 @@ en: ...@@ -33,15 +33,16 @@ en:
slogan: 'VENJOB HUMAN RESOURCE PLATFORM' slogan: 'VENJOB HUMAN RESOURCE PLATFORM'
slogan_2: 'Instantly discover the best jobs on VenJob' slogan_2: 'Instantly discover the best jobs on VenJob'
slogan_3: 'Instantly discover %{job_count} the best jobs on VenJob' slogan_3: 'Instantly discover %{job_count} the best jobs on VenJob'
search_placeholder: 'Input title, companies, locations...' search_placeholder: 'Input title, companies,...'
btn_text_search: 'Find Job' btn_text_search: 'Find Job'
all_industries: 'All industries' all_industries: 'All industries'
all_locations: 'All locations' all_locations: 'All locations'
confirm: confirm:
modal_login: 'PLEASE SIGN IN TO EXECUTE THIS FUNCTION' modal_login: 'PLEASE SIGN IN TO EXECUTE THIS FUNCTION'
result: result:
result_find: 'There are <b>%{job}</b> results matching keyword <b>%{key}</b>' result_find: 'There are &nbsp;<b>%{job}</b>&nbsp; results matching keyword &nbsp;<b>%{key}</b>&nbsp;'
no_result_find: 'No results match the keyword <b>%{key}</b>' no_result_find: 'No results match the keyword &nbsp;<b>%{key}</b>&nbsp;'
all: 'All Job'
detail: detail:
br_title: 'Result' br_title: 'Result'
btr_text_submit_cv: 'Apply Now' btr_text_submit_cv: 'Apply Now'
...@@ -50,6 +51,7 @@ en: ...@@ -50,6 +51,7 @@ en:
expiration_date: ' Expiration date' expiration_date: ' Expiration date'
experience: ' Experience' experience: ' Experience'
level: ' Level' level: ' Level'
industry: ' Industry:'
cities: cities:
ask: 'Do you want to find a job at Viet Nam or oversea?' ask: 'Do you want to find a job at Viet Nam or oversea?'
domestic: 'Viet Nam' domestic: 'Viet Nam'
...@@ -147,3 +149,7 @@ en: ...@@ -147,3 +149,7 @@ en:
user_id: '' user_id: ''
favorite: favorite:
user_id: '' user_id: ''
views:
pagination:
last: 'Last'
first: 'First'
...@@ -33,15 +33,16 @@ vi: ...@@ -33,15 +33,16 @@ vi:
slogan: 'NỀN TẢNG TUYỂN DỤNG NHÂN SỰ VENJOB' slogan: 'NỀN TẢNG TUYỂN DỤNG NHÂN SỰ VENJOB'
slogan_2: 'Khám phá ngay những việc làm tốt nhất trên VenJob' slogan_2: 'Khám phá ngay những việc làm tốt nhất trên VenJob'
slogan_3: "Khám phá ngay %{job_count} việc làm tốt nhất trên VenJob" slogan_3: "Khám phá ngay %{job_count} việc làm tốt nhất trên VenJob"
search_placeholder: 'Nhập tiêu đề, công ty, địa điểm...' search_placeholder: 'Nhập tiêu đề, công ty,...'
btn_text_search: 'Tìm việc' btn_text_search: 'Tìm việc'
all_industries: 'Tất cả nghành nghề' all_industries: 'Tất cả nghành nghề'
all_locations: 'Tất cả đỉa điểm' all_locations: 'Tất cả đỉa điểm'
confirm: confirm:
modal_login: 'VUI LÒNG ĐĂNG NHẬP ĐỂ THỰC HIỆN CHỨC NĂNG NÀY' modal_login: 'VUI LÒNG ĐĂNG NHẬP ĐỂ THỰC HIỆN CHỨC NĂNG NÀY'
result: result:
result_find: ' <b>%{job}</b> kết quả phù hợp với từ khóa <b>%{key}</b>' result_find: ' &nbsp;<b>%{job}</b>&nbsp; kết quả phù hợp với từ khóa &nbsp;<b>%{key}</b>&nbsp;'
no_result_find: 'Không kết quả phù hợp với từ khóa <b>%{key}</b>' no_result_find: 'Không kết quả phù hợp với từ khóa &nbsp;<b>%{key}</b>&nbsp;'
all: 'Tất cả công việc hiện tại'
detail: detail:
br_title: 'Kết quả tìm kiếm' br_title: 'Kết quả tìm kiếm'
btr_text_submit_cv: 'Nộp CV ngay' btr_text_submit_cv: 'Nộp CV ngay'
...@@ -50,6 +51,7 @@ vi: ...@@ -50,6 +51,7 @@ vi:
expiration_date: ' Ngày hết hạn' expiration_date: ' Ngày hết hạn'
experience: ' Kinh nghiệm' experience: ' Kinh nghiệm'
level: ' Cấp bậc' level: ' Cấp bậc'
industry: ' Ngành nghề:'
cities: cities:
ask: 'Bạn muốn tìm việc trong hay ngoài nước?' ask: 'Bạn muốn tìm việc trong hay ngoài nước?'
domestic: 'Việt Nam' domestic: 'Việt Nam'
...@@ -147,4 +149,8 @@ vi: ...@@ -147,4 +149,8 @@ vi:
user_id: '' user_id: ''
favorite: favorite:
user_id: '' user_id: ''
views:
pagination:
last: 'Cuối'
first: 'Đầu'
\ No newline at end of file
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
Rails.application.routes.draw do Rails.application.routes.draw do
get 'setting', to: 'users#set_lang', as: :set_lang get 'setting', to: 'users#set_lang', as: :set_lang
scope '(:locale)', locale: /en|vi/ do scope '(:locale)', locale: /en|vi/ do
devise_for :users, controllers: { registrations: 'registrations' } devise_for :users, controllers: { registrations: 'registrations', passwords: 'passwords'}
root 'home#index' root 'home#index'
# Search
get 'search', to: 'search#multi_search', as: :search
get 'register/:code', to: 'users#confirm_sign_up', as: :confirm_sign_up get 'register/:code', to: 'users#confirm_sign_up', as: :confirm_sign_up
get 'industries', to: 'industry#index', as: :industry_index get 'industries', to: 'industry#index', as: :industry_index
get 'cities', to: 'city#index', as: :city_index get 'cities', to: 'city#index', as: :city_index
......
...@@ -43,13 +43,14 @@ class ImportData ...@@ -43,13 +43,14 @@ class ImportData
industry_name = val['category'].gsub(',', '/').gsub('/', ' / ') industry_name = val['category'].gsub(',', '/').gsub('/', ' / ')
industry = Industry.find_or_create_by(name: industry_name.strip) industry = Industry.find_or_create_by(name: industry_name.strip)
Job.find_or_create_by(name: val['name'], company_id: company_id) do |job| record = Job.find_or_initialize_by(name: val['name'], company_id: company_id) do |job|
job.level = val['level'] job.level = val['level']
job.salary = val['salary'] job.salary = val['salary']
job.description = desc job.description = desc
job.city_ids.blank? ? job.cities << city : job.cities == city job.city_ids.blank? ? job.cities << city : job.cities == city
job.industry_ids.blank? ? job.industries << industry : job.industries == industry job.industry_ids.blank? ? job.industries << industry : job.industries == industry
end end
record.save && IndexData.indexed(record) if record.new_record?
rescue StandardError => e rescue StandardError => e
logger.error "Import_jobs: #{e}" logger.error "Import_jobs: #{e}"
end end
......
# frozen_string_literal: true
class IndexData
def logger
@logger ||= Logger.new(Rails.root.join('log', 'indexed_data_to_solr.log'))
end
def self.indexed(job)
solr = SolrSetting::SolrServer.connection
data = {}
data[:id] = job.id
data[:name] = job.name
data[:company_name] = job.company.name
data[:salary] = job.salary
data[:description] = job.description
data[:industries] = job.industry_jobs.map(&:industry).map(&:name)
data[:industry_id] = job.industry_jobs.map(&:industry_id)
data[:locations] = job.city_jobs.map(&:city).map(&:name)
data[:location_id] = job.city_jobs.map(&:city_id)
solr.add data, add_attributes: {commitWithin: 10}
rescue StandardError => e
logger.error "Indexed data to Solr have error: #{e}"
end
end
# frozen_string_literal: true
module SolrSetting
class SolrServer
URL_SERVER_SOLR = 'http://localhost:8983/solr/venjob'
def self.connection
RSolr.connect url: URL_SERVER_SOLR
end
end
end
...@@ -56,6 +56,7 @@ class CrawlerJob < Crawler ...@@ -56,6 +56,7 @@ class CrawlerJob < Crawler
description: data[:description]) description: data[:description])
create_industry_relation(data[:industry_name], job) create_industry_relation(data[:industry_name], job)
create_city_relation(data[:city_name], job) create_city_relation(data[:city_name], job)
IndexData.indexed(job)
rescue StandardError => e rescue StandardError => e
logger.error "Crawler data jobs has error: #{e}" logger.error "Crawler data jobs has error: #{e}"
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment