# ===================================================================================================== # 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 # # 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' require 'json' $elasticsearch_url = ENV.fetch('ELASTICSEARCH_URL', 'http://localhost:9200') # ----- Check for Elasticsearch ------------------------------------------------------------------- required_elasticsearch_version = '6' docker_command =<<-CMD.gsub(/\s{1,}/, ' ').strip docker run \ --name elasticsearch-rails-searchapp \ --publish 9200:9200 \ --env "discovery.type=single-node" \ --env "cluster.name=elasticsearch-rails" \ --env "cluster.routing.allocation.disk.threshold_enabled=false" \ --rm \ docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.0 CMD begin cluster_info = Net::HTTP.get(URI.parse($elasticsearch_url)) rescue Errno::ECONNREFUSED => e say_status "ERROR", "Cannot connect to Elasticsearch on <#{$elasticsearch_url}>\n\n", :red say_status "", "The application requires an Elasticsearch cluster running, " + "but no cluster has been found on <#{$elasticsearch_url}>." say_status "", "The easiest way of launching Elasticsearch is by running it with Docker (https://www.docker.com/get-docker):\n\n" say_status "", docker_command + "\n" exit(1) rescue StandardError => e say_status "ERROR", "#{e.class}: #{e.message}", :red exit(1) end cluster_info = JSON.parse(cluster_info) unless cluster_info['version'] say_status "ERROR", "Cannot determine Elasticsearch version from <#{$elasticsearch_url}>", :red say_status "", JSON.dump(cluster_info), :red exit(1) end if cluster_info['version']['number'] < required_elasticsearch_version say_status "ERROR", "The application requires Elasticsearch version #{required_elasticsearch_version} or higher, found version #{cluster_info['version']['number']}.\n\n", :red say_status "", "The easiest way of launching Elasticsearch is by running it with Docker (https://www.docker.com/get-docker):\n\n" say_status "", docker_command + "\n" exit(1) end # ----- 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' 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: 'https://github.com/elasticsearch/elasticsearch-ruby.git' gem 'elasticsearch-model', git: 'https://github.com/elasticsearch/elasticsearch-rails.git' gem 'elasticsearch-rails', git: 'https://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{