# ===================================================================================================== # Template for generating a no-frills Rails application with support for Elasticsearch full-text search # ===================================================================================================== # # This file creates a basic, fully working Rails application with support for Elasticsearch full-text # search via the `elasticsearch-rails` gem; https://github.com/elasticsearch/elasticsearch-rails. # # Requirements: # ------------- # # * Git # * Ruby >= 1.9.3 # * Rails >= 5 # * Java >= 8 (for Elasticsearch) # # Usage: # ------ # # $ rails new searchapp --skip --skip-bundle --template https://raw.github.com/elasticsearch/elasticsearch-rails/master/elasticsearch-rails/lib/rails/templates/01-basic.rb # # ===================================================================================================== require 'uri' require 'net/http' at_exit do pid = File.read("#{destination_root}/tmp/pids/elasticsearch.pid") rescue nil if pid say_status "Stop", "Elasticsearch", :yellow run "kill #{pid}" end end $elasticsearch_url = ENV.fetch('ELASTICSEARCH_URL', 'http://localhost:9200') # ----- Check & download Elasticsearch ------------------------------------------------------------ cluster_info = Net::HTTP.get(URI.parse($elasticsearch_url)) rescue nil cluster_info = JSON.parse(cluster_info) if cluster_info if cluster_info.nil? || cluster_info['version']['number'] < '5' # Change the port when incompatible Elasticsearch version is running on localhost:9200 if $elasticsearch_url == 'http://localhost:9200' && cluster_info && cluster_info['version']['number'] < '5' $change_port = '9280' $elasticsearch_url = "http://localhost:#{$change_port}" end COMMAND = <<-COMMAND.gsub(/^ /, '') curl -# -O "https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.1.tar.gz" tar -zxf elasticsearch-5.2.1.tar.gz rm -f elasticsearch-5.2.1.tar.gz ./elasticsearch-5.2.1/bin/elasticsearch -d -p #{destination_root}/tmp/pids/elasticsearch.pid #{$change_port.nil? ? '' : "-E http.port=#{$change_port}" } COMMAND puts "\n" say_status "ERROR", "Elasticsearch not running!\n", :red puts '-'*80 say_status '', "It appears that Elasticsearch 5 is not running on this machine." say_status '', "Is it installed? Do you want me to install and run it for you with this command?\n\n" COMMAND.each_line { |l| say_status '', "$ #{l}" } puts say_status '', "(To uninstall, just remove the generated application directory.)" puts '-'*80, '' if yes?("Install Elasticsearch?", :bold) puts say_status "Install", "Elasticsearch", :yellow java_info = `java -version 2>&1` unless java_info.match /1\.[8-9]/ puts say_status "ERROR", "Required Java version (1.8) not found, exiting...", :red exit(1) end commands = COMMAND.split("\n") exec = commands.pop inside("vendor") do commands.each { |command| run command } run "(#{exec})" # Launch Elasticsearch in subshell end # Wait for Elasticsearch to be up... # system <<-COMMAND until $(curl --silent --head --fail #{$elasticsearch_url} > /dev/null 2>&1); do printf '.'; sleep 1 done COMMAND end end unless ENV['RAILS_NO_ES_INSTALL'] # ----- Application skeleton ---------------------------------------------------------------------- run "touch tmp/.gitignore" append_to_file ".gitignore", "vendor/elasticsearch-5.2.1/\n" git :init git add: "." git commit: "-m 'Initial commit: Clean application'" # ----- Add README -------------------------------------------------------------------------------- puts say_status "README", "Adding Readme...\n", :yellow puts '-'*80, ''; sleep 0.25 remove_file 'README.md' create_file 'README.md', <<-README # Ruby on Rails and Elasticsearch: Example application This application is an example of integrating the {Elasticsearch}[http://www.elasticsearch.org] search engine with the {Ruby On Rails}[http://rubyonrails.org] web framework. It has been generated by application templates available at https://github.com/elasticsearch/elasticsearch-rails/tree/master/elasticsearch-rails/lib/rails/templates. ## [1] Basic The `basic` version provides a simple integration for a simple Rails model, `Article`, showing how to include the search engine support in your model, automatically index changes to records, and use a form to perform simple search require 'requests.' README git add: "." git commit: "-m '[01] Added README for the application'" # ----- Use Thin ---------------------------------------------------------------------------------- begin require 'thin' puts say_status "Rubygems", "Adding Thin into Gemfile...\n", :yellow puts '-'*80, ''; gem 'thin' rescue LoadError end # ----- Auxiliary gems ---------------------------------------------------------------------------- gem 'mocha', group: 'test', require: 'mocha/api' gem 'rails-controller-testing', group: 'test' # ----- Remove CoffeeScript, Sass and "all that jazz" --------------------------------------------- comment_lines 'Gemfile', /gem 'coffee/ comment_lines 'Gemfile', /gem 'sass/ comment_lines 'Gemfile', /gem 'uglifier/ uncomment_lines 'Gemfile', /gem 'therubyracer/ # ----- Add gems into Gemfile --------------------------------------------------------------------- puts say_status "Rubygems", "Adding Elasticsearch libraries into Gemfile...\n", :yellow puts '-'*80, ''; sleep 0.75 gem 'elasticsearch', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git' gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git' gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git' git add: "Gemfile*" git commit: "-m 'Added libraries into Gemfile'" # ----- Disable asset logging in development ------------------------------------------------------ puts say_status "Application", "Disabling asset logging in development...\n", :yellow puts '-'*80, ''; sleep 0.25 environment 'config.assets.logger = false', env: 'development' environment 'config.assets.quiet = true', env: 'development' git add: "config/" git commit: "-m 'Disabled asset logging in development'" # ----- Install gems ------------------------------------------------------------------------------ puts say_status "Rubygems", "Installing Rubygems...", :yellow puts '-'*80, '' run "bundle install" # ----- Generate Article resource ----------------------------------------------------------------- puts say_status "Model", "Generating the Article resource...", :yellow puts '-'*80, ''; sleep 0.75 generate :scaffold, "Article title:string content:text published_on:date" route "root to: 'articles#index'" rake "db:migrate" git add: "." git commit: "-m 'Added the generated Article resource'" # ----- Add Elasticsearch integration into the model ---------------------------------------------- puts say_status "Model", "Adding search support into the Article model...", :yellow puts '-'*80, ''; sleep 0.25 run "rm -f app/models/article.rb" file 'app/models/article.rb', <<-CODE class Article < ActiveRecord::Base include Elasticsearch::Model include Elasticsearch::Model::Callbacks #{'attr_accessible :title, :content, :published_on' if Rails::VERSION::STRING < '4'} end CODE git commit: "-a -m 'Added Elasticsearch support into the Article model'" # ----- Add Elasticsearch integration into the interface ------------------------------------------ puts say_status "Controller", "Adding controller action, route, and HTML for searching...", :yellow puts '-'*80, ''; sleep 0.25 inject_into_file 'app/controllers/articles_controller.rb', before: %r|^\s*# GET /articles/1$| do <<-CODE # GET /articles/search def search @articles = Article.search(params[:q]).records render action: "index" end CODE end inject_into_file 'app/views/articles/index.html.erb', after: %r{