├── log └── .keep ├── app ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ └── .keep │ ├── role.rb │ ├── genre.rb │ ├── crew.rb │ └── movie.rb ├── assets │ ├── images │ │ └── .keep │ ├── stylesheets │ │ ├── movies.sass │ │ ├── landings.sass │ │ ├── navbar-form.css │ │ └── application.sass │ └── javascripts │ │ └── application.coffee ├── controllers │ ├── concerns │ │ └── .keep │ ├── landings_controller.rb │ ├── application_controller.rb │ └── movies_controller.rb ├── helpers │ ├── movies_helper.rb │ └── application_helper.rb ├── presenters │ ├── bucket_presenter.rb │ └── aggregation_presenter.rb ├── views │ ├── movies │ │ ├── index.html.erb │ │ └── _movie.html.erb │ ├── layouts │ │ ├── shared │ │ │ ├── _footer.html.erb │ │ │ └── _navigation.html.erb │ │ ├── landings.html.erb │ │ └── application.html.erb │ ├── aggregations │ │ └── _aggregation.html.erb │ └── landings │ │ └── show.html.erb ├── jobs │ └── indexer_job.rb └── queries │ └── movies_query.rb ├── lib ├── assets │ └── .keep └── tasks │ ├── .keep │ ├── elasticsearch.rake │ └── omdb.thor ├── public ├── favicon.ico ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── test ├── helpers │ └── .keep ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── genre_test.rb │ ├── crew_test.rb │ ├── role_test.rb │ └── movie_test.rb ├── controllers │ ├── .keep │ └── movies_controller_test.rb ├── fixtures │ ├── .keep │ ├── crews.yml │ ├── movies.yml │ ├── genres.yml │ └── roles.yml ├── integration │ └── .keep ├── jobs │ └── indexer_job_test.rb └── test_helper.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── bin ├── web ├── worker ├── bundle ├── rake ├── rails ├── spring └── setup ├── config ├── sidekiq.yml ├── boot.rb ├── initializers │ ├── cookies_serializer.rb │ ├── session_store.rb │ ├── mime_types.rb │ ├── filter_parameter_logging.rb │ ├── backtrace_silencers.rb │ ├── elasticsearch.rb │ ├── assets.rb │ ├── wrap_parameters.rb │ ├── inflections.rb │ └── sidekiq.rb ├── environment.rb ├── routes.rb ├── puma.rb ├── locales │ └── en.yml ├── secrets.yml ├── application.rb ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── database.yml.example └── database.yml ├── db ├── migrate │ ├── 20150501102639_drop_crews_movies.rb │ ├── 20150501104039_add_release_date_to_movies.rb │ ├── 20150501071546_create_crews.rb │ ├── 20150419151922_create_genres.rb │ ├── 20150419151848_create_movies.rb │ ├── 20150501072034_create_crews_movies.rb │ ├── 20150419152045_create_genres_movies.rb │ ├── 20150501102555_create_roles.rb │ └── 20150501101641_add_fields_to_movies.rb ├── seeds.rb └── schema.rb ├── config.ru ├── Rakefile ├── .drone.sec ├── Dockerfile ├── .gitignore ├── LICENSE ├── README.md ├── Gemfile ├── .drone.yml └── Gemfile.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/movies.sass: -------------------------------------------------------------------------------- 1 | body.movies.index 2 | -------------------------------------------------------------------------------- /bin/web: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | bundle exec puma -C config/puma.rb -------------------------------------------------------------------------------- /app/helpers/movies_helper.rb: -------------------------------------------------------------------------------- 1 | module MoviesHelper 2 | end 3 | -------------------------------------------------------------------------------- /bin/worker: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | bundle exec sidekiq -C config/sidekiq.yml -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /lib/tasks/elasticsearch.rake: -------------------------------------------------------------------------------- 1 | require 'elasticsearch/rails/tasks/import' -------------------------------------------------------------------------------- /config/sidekiq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | :concurrency: 4 3 | :queues: 4 | - default 5 | - elasticsearch -------------------------------------------------------------------------------- /app/models/role.rb: -------------------------------------------------------------------------------- 1 | class Role < ActiveRecord::Base 2 | belongs_to :movie 3 | belongs_to :crew 4 | end 5 | -------------------------------------------------------------------------------- /test/models/genre_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class GenreTest < ActiveSupport::TestCase 4 | 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/landings_controller.rb: -------------------------------------------------------------------------------- 1 | class LandingsController < ApplicationController 2 | def show 3 | 4 | end 5 | end -------------------------------------------------------------------------------- /app/assets/javascripts/application.coffee: -------------------------------------------------------------------------------- 1 | #= require jquery 2 | #= require jquery_ujs 3 | #= require turbolinks 4 | #= require bootstrap -------------------------------------------------------------------------------- /app/models/genre.rb: -------------------------------------------------------------------------------- 1 | class Genre < ActiveRecord::Base 2 | has_and_belongs_to_many :movies 3 | 4 | validates :name, uniqueness: true 5 | end 6 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /db/migrate/20150501102639_drop_crews_movies.rb: -------------------------------------------------------------------------------- 1 | class DropCrewsMovies < ActiveRecord::Migration 2 | def change 3 | drop_table :crews_movies 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/crews.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | mark_ruffalo: 4 | name: Mark Ruffalo 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/landings.sass: -------------------------------------------------------------------------------- 1 | body.landings.show 2 | div#search-bar 3 | padding-top: 110px 4 | h1 5 | font-weight: bold 6 | margin-bottom: 40px -------------------------------------------------------------------------------- /app/models/crew.rb: -------------------------------------------------------------------------------- 1 | class Crew < ActiveRecord::Base 2 | has_many :roles 3 | has_many :movies, through: :roles 4 | 5 | validates :name, uniqueness: true 6 | end 7 | -------------------------------------------------------------------------------- /test/models/crew_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CrewTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/models/role_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RoleTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /test/jobs/indexer_job_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class IndexerJobTest < ActiveJob::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_moviedb_session' 4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /db/migrate/20150501104039_add_release_date_to_movies.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseDateToMovies < ActiveRecord::Migration 2 | def change 3 | add_column :movies, :release_date, :date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/controllers/movies_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MoviesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/fixtures/movies.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | avengers: 4 | name: The Avengers 5 | synopsis: Superheroes fight robot 6 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /db/migrate/20150501071546_create_crews.rb: -------------------------------------------------------------------------------- 1 | class CreateCrews < ActiveRecord::Migration 2 | def change 3 | create_table :crews do |t| 4 | t.string :name 5 | 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/fixtures/genres.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | action: 4 | name: Action 5 | 6 | adventure: 7 | name: Adventure 8 | 9 | thriller: 10 | name: Thriller 11 | -------------------------------------------------------------------------------- /db/migrate/20150419151922_create_genres.rb: -------------------------------------------------------------------------------- 1 | class CreateGenres < ActiveRecord::Migration 2 | def change 3 | create_table :genres do |t| 4 | t.string :name 5 | 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /test/fixtures/roles.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | movie_id: 5 | crew_id: 6 | job: MyString 7 | 8 | two: 9 | movie_id: 10 | crew_id: 11 | job: MyString 12 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150419151848_create_movies.rb: -------------------------------------------------------------------------------- 1 | class CreateMovies < ActiveRecord::Migration 2 | def change 3 | create_table :movies do |t| 4 | t.string :name 5 | t.text :synopsis 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/presenters/bucket_presenter.rb: -------------------------------------------------------------------------------- 1 | class BucketPresenter < Struct.new(:bucket) 2 | def id 3 | bucket['key'].split('|').first 4 | end 5 | 6 | def name 7 | bucket['key'].split('|').last 8 | end 9 | 10 | def count 11 | bucket['doc_count'] 12 | end 13 | end -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | resources :movies, only: [:show, :index] do 3 | get 'search/*query', to: 'movies#index', as: :search, on: :collection 4 | end 5 | 6 | resource :landing, only: [:show] 7 | 8 | root to: 'landings#show' 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20150501072034_create_crews_movies.rb: -------------------------------------------------------------------------------- 1 | class CreateCrewsMovies < ActiveRecord::Migration 2 | def change 3 | create_table :crews_movies, id: false do |t| 4 | t.integer :crew_id, index: true, unique: true 5 | t.integer :movie_id, index: true 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20150419152045_create_genres_movies.rb: -------------------------------------------------------------------------------- 1 | class CreateGenresMovies < ActiveRecord::Migration 2 | def change 3 | create_table :genres_movies, id: false do |t| 4 | t.integer :genre_id, index: true, unique: true 5 | t.integer :movie_id, index: true 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/navbar-form.css: -------------------------------------------------------------------------------- 1 | .navbar-form .input-group { 2 | display: table; 3 | } 4 | .navbar-form .input-group .input-group-addon, 5 | .navbar-form .input-group .input-group-btn { 6 | white-space: nowrap; 7 | width: 1%; 8 | } 9 | .navbar-form .input-group .form-control { 10 | width: 100%; 11 | } -------------------------------------------------------------------------------- /app/assets/stylesheets/application.sass: -------------------------------------------------------------------------------- 1 | @import "bootstrap-sprockets" 2 | @import "bootstrap" 3 | @import "navbar-form" 4 | @import "landings" 5 | @import "movies" 6 | 7 | body 8 | font-family: 'Open Sans', sans-serif 9 | 10 | a:hover 11 | text-decoration: none 12 | 13 | form.navbar-form 14 | margin-top: 10px 15 | 16 | footer 17 | padding-top: 40px -------------------------------------------------------------------------------- /app/views/movies/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <% @movies.each do |movie| %> 4 | <%= render 'movie', movie: movie %> 5 | <% end %> 6 |
7 |
8 | <% @aggs.each do |agg| %> 9 | <%= render 'aggregations/aggregation', agg: agg %> 10 | <% end %> 11 |
12 |
-------------------------------------------------------------------------------- /app/presenters/aggregation_presenter.rb: -------------------------------------------------------------------------------- 1 | class AggregationPresenter < Struct.new(:aggregation) 2 | def name 3 | aggregation.first.split('_').first.pluralize.titleize 4 | end 5 | 6 | def kind 7 | aggregation.first.split('_').first.pluralize 8 | end 9 | 10 | def buckets 11 | aggregation[1].id_and_name.buckets.map{ |b| BucketPresenter.new(b) } 12 | end 13 | end -------------------------------------------------------------------------------- /db/migrate/20150501102555_create_roles.rb: -------------------------------------------------------------------------------- 1 | class CreateRoles < ActiveRecord::Migration 2 | def change 3 | create_table :roles do |t| 4 | t.references :movie, index: true 5 | t.references :crew, index: true 6 | t.string :job 7 | 8 | t.timestamps null: false 9 | end 10 | add_foreign_key :roles, :movies 11 | add_foreign_key :roles, :crews 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20150501101641_add_fields_to_movies.rb: -------------------------------------------------------------------------------- 1 | class AddFieldsToMovies < ActiveRecord::Migration 2 | def change 3 | add_column :movies, :country, :string 4 | add_column :movies, :year, :integer 5 | add_column :movies, :review, :float 6 | add_column :movies, :rating, :string 7 | add_column :movies, :runtime, :integer 8 | add_column :movies, :language, :string 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | require 'minitest/reporters' 5 | 6 | Minitest::Reporters.use! 7 | 8 | class ActiveSupport::TestCase 9 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /app/views/layouts/shared/_footer.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/initializers/elasticsearch.rb: -------------------------------------------------------------------------------- 1 | ELASTICSEARCH_CONFIG = proc do 2 | host = ENV['ELASTIC_HOST'] 3 | port = ENV['ELASTIC_PORT'] 4 | 5 | elastic_ready = host.present? and port.present? 6 | 7 | elasticsearch_url = if elastic_ready 8 | "http://#{host}:#{port}" 9 | else 10 | "http://localhost:9200" 11 | end 12 | end 13 | 14 | Elasticsearch::Model.client = Elasticsearch::Client.new(url: ELASTICSEARCH_CONFIG.call, retry_on_failure: 5) 15 | -------------------------------------------------------------------------------- /.drone.sec: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Ff3TOUvYCUyh7vtMjy9G97NytlkLyy4qrnwYPB9Ppx-NAhRzE4cRXjy9XfFW_akZX9_gtcH7zhTFmHgPVRxxMjMD1r0zw-DmnjrN6PfMj_wFaaDb6bchvRZAO670oWfUQZgLTtGQNyKlTmOmvL8a86A5hDYBA9T6SYd8vtD6cnHx06HB6rgfCSzdEoPa2raygoFc2Zt8A48mlWFPA6-i5FoadTeZsRrHc-QgRP23QlvXc8YBMuF44fk0i3HP63ICF-TDwz6vzp49sx7gPkkG8UNbuyw6IbTEDBFFk4M4qt_9xFoBFsU9VLFmzY4WbkE_8-dq_AcJkXsynIvNJazDGQ.fWshR-PO8uyt4dJR.v3whTHW6j-pjhzyyi0SXgQFhG85ETd65VuUHhkCJ2neMJQtrI6g2r36VoGdJIw.U8_BNUPOl-pVio26M_HpgQ -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | threads_count = Integer(ENV['MAX_THREADS'] || 16) 2 | threads threads_count, threads_count 3 | 4 | preload_app! 5 | 6 | rackup DefaultRackup 7 | port ENV['PORT'] || 4000 8 | environment ENV['RACK_ENV'] || 'development' 9 | 10 | on_worker_boot do 11 | # Worker specific setup for Rails 4.1+ 12 | # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot 13 | ActiveRecord::Base.establish_connection 14 | end -------------------------------------------------------------------------------- /app/jobs/indexer_job.rb: -------------------------------------------------------------------------------- 1 | class IndexerJob < ActiveJob::Base 2 | queue_as :elasticsearch 3 | 4 | def perform(operation, record_id) 5 | self.send(operation, record_id) 6 | end 7 | 8 | private 9 | 10 | def index(record_id) 11 | record = Movie.find(record_id) 12 | record.__elasticsearch__.index_document 13 | end 14 | 15 | def delete(record_id) 16 | client = Movie.__elasticsearch__.client 17 | client.delete index: Movie.index_name, type: Movie.model_name.to_s.downcase, id: record_id 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/aggregations/_aggregation.html.erb: -------------------------------------------------------------------------------- 1 |

<%= agg.name %>

2 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(File::PATH_SEPARATOR) } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /app/views/landings/show.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/movies_controller.rb: -------------------------------------------------------------------------------- 1 | class MoviesController < ApplicationController 2 | include Refiner::Query 3 | 4 | before_filter :beautify_search_url, only: [:index] 5 | 6 | def index 7 | search = Movie.custom_search(segmented_query) 8 | @aggs = search.response.aggregations.map { |a| AggregationPresenter.new(a) } 9 | @movies = search.results 10 | end 11 | 12 | private 13 | 14 | def beautify_search_url 15 | redirect_to search_movies_path(query: "keyword/#{params[:q]}") if params[:q].present? 16 | end 17 | 18 | def segmented_query 19 | segment_refiner_query_by("crews", "keyword", "genres") 20 | end 21 | 22 | helper_method :segmented_query 23 | end 24 | -------------------------------------------------------------------------------- /app/views/layouts/landings.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= content_for(:title) || "Movie Database" %> 5 | 6 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 7 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 8 | <%= csrf_meta_tags %> 9 | 10 | 11 |
12 | <%= yield %> 13 |
14 | <%= render 'layouts/shared/footer' %> 15 | 16 | 17 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:2.3.1-alpine 2 | MAINTAINER Zack Siri 3 | 4 | RUN apk --update add --virtual build-dependencies \ 5 | build-base \ 6 | libxml2-dev \ 7 | libxslt-dev \ 8 | postgresql-dev \ 9 | nodejs \ 10 | tzdata \ 11 | && rm -rf /var/cache/apk/* 12 | 13 | 14 | RUN mkdir /usr/src/app 15 | WORKDIR /usr/src/app 16 | 17 | COPY . /usr/src/app 18 | 19 | RUN gem update bundler 20 | RUN bundle install --path vendor/bundle --without development test doc --deployment --jobs=4 21 | RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= content_for(:title) || "Movie Database" %> 5 | 6 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 7 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 8 | <%= csrf_meta_tags %> 9 | 10 | 11 | <%= render 'layouts/shared/navigation' %> 12 |
13 | <%= yield %> 14 |
15 | <%= render 'layouts/shared/footer' %> 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/models/movie_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class MovieTest < ActiveSupport::TestCase 4 | 5 | def setup 6 | @movie = movies(:avengers) 7 | end 8 | 9 | test "add genres" do 10 | assert_difference('Genre.count', 1) do 11 | @movie.add_many 'Genre', ['Comedy', 'Action'] 12 | end 13 | 14 | assert_equal 2, @movie.genres.count 15 | end 16 | 17 | test "add crews" do 18 | assert_difference('Crew.count', 1) do 19 | @movie.add_many 'Crew', ['Scarlett Johansson', 'Mark Ruffalo'] 20 | end 21 | 22 | assert_equal 2, @movie.crews.count 23 | end 24 | 25 | test "add wrong type" do 26 | assert_raises Movie::RelationError do 27 | @movie.add_many 'Blah', ['Stuff', 'Another Stuff'] 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /config/initializers/sidekiq.rb: -------------------------------------------------------------------------------- 1 | REDIS_CONN = proc do 2 | host = ENV['REDIS_HOST'] 3 | port = ENV['REDIS_PORT'] 4 | 5 | redis_ready = host.present? and port.present? 6 | 7 | redis_url = if redis_ready 8 | "redis://#{host}:#{port}/" 9 | else 10 | "redis://localhost:6379/" 11 | end 12 | 13 | r = Redis.new(url: redis_url) 14 | Redis::Namespace.new("sidekiq", redis: r) 15 | end 16 | 17 | Sidekiq.configure_client do |config| 18 | config.redis = ConnectionPool.new(size: Sidekiq.options[:concurrency] + 2, timeout: 1, &REDIS_CONN) 19 | end 20 | 21 | Sidekiq.configure_server do |config| 22 | config.redis = ConnectionPool.new(size: Sidekiq.options[:concurrency] + 4, timeout: 1, &REDIS_CONN) 23 | 24 | config.server_middleware do |chain| 25 | chain.remove Sidekiq::Middleware::Server::RetryJobs 26 | end 27 | end -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | capybara-*.html 3 | .rspec 4 | /log 5 | /tmp 6 | /db/*.sqlite3 7 | /db/*.sqlite3-journal 8 | /public/system 9 | /coverage/ 10 | /spec/tmp 11 | **.orig 12 | rerun.txt 13 | pickle-email-*.html 14 | .DS_Store 15 | .env.prod 16 | 17 | # TODO Comment out these rules if you are OK with secrets being uploaded to the repo 18 | config/initializers/secret_token.rb 19 | config/secrets.yml 20 | 21 | ## Environment normalisation: 22 | /.bundle 23 | /vendor/bundle 24 | 25 | # these should all be checked in to normalise the environment: 26 | # Gemfile.lock, .ruby-version, .ruby-gemset 27 | 28 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 29 | .rvmrc 30 | 31 | # if using bower-rails ignore default bower_components path bower.json files 32 | /vendor/assets/bower_components 33 | *.bowerrc 34 | bower.json 35 | 36 | # Ignore pow environment settings 37 | .powenv 38 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: 3154eef66be89b6ef4c7bbc3c0da6f43ce440ec5881a3e100fb0afcbfd1791713707ed71fd4c4c1db450c38cabd3b9bff194cd9ee709c084f866c2fd822b0e46 15 | 16 | test: 17 | secret_key_base: ef551eb22e04a35c500c67c61f61813c5abb6ae5403ab6e3150604caa7203400c68aa4aa5ac896a18ccac0b1f1548f33c50b75fe5d163376e0257c19ae419a2f 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /app/views/movies/_movie.html.erb: -------------------------------------------------------------------------------- 1 | <%= content_tag :div, class: 'panel panel-default', id: "movie_#{movie.id}" do %> 2 |
3 |
4 |
5 |

<%= link_to movie.name, movie_path(movie.id) %>

6 |
7 |
8 |
9 | <% movie.genres.each do |genre| %> 10 | <%= genre.name %> 11 | <% end %> 12 |
13 |
14 |
15 |
16 |
17 |

<%= movie.synopsis %>

18 |
19 | <%= movie.runtime.to_s + " minutes" if movie.runtime.present? %> 20 | <%= "Review: " + movie.review.to_s if movie.review.present? %> 21 |
22 |
23 | <% movie.crews.each do |crew| %> 24 | <%= crew.name %> 25 | <% end %> 26 |
27 | <% end %> -------------------------------------------------------------------------------- /app/views/layouts/shared/_navigation.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Codemy.net 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # moviedb 2 | 3 | Example App for Elasticsearch Series on [Codemy.net](https://www.codemy.net/posts/search/keyword/elasticsearch) 4 | 5 | ## Dependencies 6 | 7 | + PostgreSQL 9.3+ 8 | + Elasticsearch 1.7+ 9 | + Redis 2.8+ 10 | 11 | ## Setup 12 | 13 | Copy `database.yml.example` as `database.yml` then run 14 | 15 | ```shell 16 | rake db:create db:schema:load 17 | ``` 18 | 19 | You will need to download the example data dump from here [Data Dump](https://www.dropbox.com/s/reim7b8fviwubn9/moviedb_development.dump?dl=0) 20 | 21 | Once you have the dump file run this command to import it into your local database 22 | 23 | ```shell 24 | pg_restore --verbose --clean --no-acl --no-owner -h localhost -U user -d yourdb moviedb_development.dump 25 | ``` 26 | 27 | Once you have the data in your database you will need to index it into your elasticsearch 28 | 29 | ```shell 30 | rails c 31 | ``` 32 | 33 | Once you are in the console use this, snippet of code. It will queue all the movies in the database for indexing. 34 | 35 | ```ruby 36 | Movie.find_each do |m| 37 | m.index_document 38 | end 39 | ``` 40 | 41 | Start your sidekiq process so it runs the actual indexing 42 | 43 | ```shell 44 | bundle exec sidekiq -q elasticsearch 45 | ``` -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | require 'elasticsearch/rails/instrumentation' 5 | 6 | # Require the gems listed in Gemfile, including any gems 7 | # you've limited to :test, :development, or :production. 8 | Bundler.require(*Rails.groups) 9 | 10 | module Moviedb 11 | class Application < Rails::Application 12 | # Settings in config/environments/* take precedence over those specified here. 13 | # Application configuration should go into files in config/initializers 14 | # -- all .rb files in that directory are automatically loaded. 15 | 16 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 17 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 18 | # config.time_zone = 'Central Time (US & Canada)' 19 | 20 | config.autoload_paths += %W(#{config.root}/presenters 21 | #{config.root}/queries) 22 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 23 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 24 | # config.i18n.default_locale = :de 25 | config.active_job.queue_adapter = :sidekiq 26 | 27 | # Do not swallow errors in after_commit/after_rollback callbacks. 28 | config.active_record.raise_in_transactional_callbacks = true 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | 9 | 10 | ["Action", "Crime", "Drama", "Animation", "Adventure", "Comedy"].each do |genre| 11 | Genre.create(name: genre) 12 | end 13 | 14 | [ 15 | {name: "Frozen", synopsis: "When the newly crowned Queen Elsa accidentally uses her power to turn things into ice to curse her home in infinite winter, her sister, Anna, teams up with a mountain man, his playful reindeer, and a snowman to change the weather condition.", genres: ["Animation", "Adventure", "Comedy"]}, 16 | {name: "Big Hero 6", synopsis: "The special bond that develops between plus-sized inflatable robot Baymax, and prodigy Hiro Hamada, who team up with a group of friends to form a band of high-tech heroes.", genres: ["Animation", "Action", "Adventure"]}, 17 | {name: "Blackhat", synopsis: "A furloughed convict and his American and Chinese partners hunt a high-level cybercrime network from Chicago to Los Angeles to Hong Kong to Jakarta.", genres: ["Action", "Crime", "Drama"]} 18 | ].each do |data| 19 | movie = Movie.create(name: data[:name], synopsis: data[:synopsis]) 20 | 21 | movie.genres.push(Genre.where(name: data[:genres])) 22 | end 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/queries/movies_query.rb: -------------------------------------------------------------------------------- 1 | module MoviesQuery 2 | def self.build(keyword) 3 | { 4 | multi_match: { 5 | query: keyword, 6 | type: "best_fields", # possible values "most_fields", "phrase", "phrase_prefix", "cross_fields" 7 | fields: ["name^9", "synopsis^8", "year", "language^7", "country", "genres.name", "crews.name^10"], 8 | operator: "and" 9 | } 10 | } 11 | end 12 | 13 | module Aggregate 14 | def self.build 15 | { 16 | crew_aggregation: { 17 | nested: { path: "crews" }, 18 | aggs: generate_aggregation_for("crews") 19 | }, 20 | genre_aggregation: { 21 | nested: { path: "genres" }, 22 | aggs: generate_aggregation_for("genres") 23 | } 24 | } 25 | end 26 | 27 | def self.generate_aggregation_for(agg_type) 28 | { 29 | id_and_name: { 30 | terms: { script: "doc['#{agg_type}.id'].value + '|' + doc['#{agg_type}.name'].value", size: 15 } 31 | } 32 | } 33 | end 34 | end 35 | 36 | module Filter 37 | def self.build(segments) 38 | { 39 | bool: { 40 | must: nested_terms_filter(segments) 41 | } 42 | } 43 | end 44 | 45 | def self.nested_terms_filter(segments) 46 | segments.keys.map do |path| 47 | { 48 | nested: { 49 | path: path, 50 | filter: { 51 | terms: { "#{path}.id": segments[path].split(',').map(&:to_i) } 52 | } 53 | } 54 | } 55 | end 56 | end 57 | end 58 | end -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /lib/tasks/omdb.thor: -------------------------------------------------------------------------------- 1 | require 'thor' 2 | require File.expand_path('config/environment.rb') 3 | 4 | class Omdb < Thor 5 | 6 | desc "import", "Import data from omdb" 7 | def import 8 | movie_names = Movie.pluck(:name) 9 | movies = Sequel.connect('postgres://zacksiri@localhost:5432/omdb')[:movies] 10 | movies.order(:ID).each do |mdb| 11 | movie = Movie.create do |m| 12 | m.name = mdb[:Title] 13 | m.synopsis = mdb[:FullPlot] unless mdb[:FullPlot] == 'N/A' 14 | m.year = mdb[:Year].to_i 15 | m.country = mdb[:Country] unless mdb[:Country] == 'N/A' 16 | m.language = mdb[:Language] unless mdb[:Language] == 'N/A' 17 | m.runtime = mdb[:Runtime].to_i unless mdb[:Runtime] == 'N/A' 18 | m.review = mdb[:imdbRating].to_f unless mdb[:imdbRating] == 'N/A' 19 | m.release_date = Date.parse(mdb[:Released]) if mdb[:Released] 20 | end 21 | 22 | movie.add_many('Genre', mdb[:Genre].split(',').map(&:strip)) 23 | 24 | if movie.persisted? 25 | extract_crew('Director', movie, mdb[:Director]) unless mdb[:Director] == 'N/A' 26 | extract_crew('Writer', movie, mdb[:Writer]) unless mdb[:Writer] == 'N/A' 27 | extract_crew('Cast', movie, mdb[:Cast]) unless mdb[:Cast] == 'N/A' 28 | end 29 | 30 | puts "-----> Imported #{mdb[:Title]}" 31 | end 32 | end 33 | 34 | no_tasks do 35 | def extract_crew(role, movie, data) 36 | data.split(',').map { |n| n.gsub(/\(\S*\)/, '') } 37 | .map(&:strip).each do |crew_name| 38 | crew = Crew.where(name: crew_name).first_or_create! 39 | Role.where(crew: crew, movie: movie, job: role).first_or_create! 40 | end 41 | end 42 | end 43 | end -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | ruby '2.3.1' 4 | 5 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 6 | gem 'rails', '4.2.6' 7 | # Use postgresql as the database for Active Record 8 | gem 'pg' 9 | # Use SCSS for stylesheets 10 | gem 'sass-rails', '~> 5.0' 11 | # Use Uglifier as compressor for JavaScript assets 12 | gem 'uglifier', '>= 1.3.0' 13 | # Use CoffeeScript for .coffee assets and views 14 | gem 'coffee-rails', '~> 4.1.0' 15 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 16 | # gem 'therubyracer', platforms: :ruby 17 | 18 | # Use jquery as the JavaScript library 19 | gem 'jquery-rails' 20 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 21 | gem 'turbolinks' 22 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 23 | gem 'jbuilder', '~> 2.0' 24 | # bundle exec rake doc:rails generates the API under doc/api. 25 | gem 'sdoc', '~> 0.4.0', group: :doc 26 | 27 | gem 'redis' 28 | gem 'redis-namespace' 29 | 30 | gem 'elasticsearch-rails' 31 | gem 'elasticsearch-model' 32 | gem 'bootstrap-sass' 33 | gem 'sidekiq' 34 | gem 'refiner' 35 | gem 'sequel' 36 | 37 | 38 | group :production do 39 | gem 'activerecord-nulldb-adapter' 40 | end 41 | 42 | group :development do 43 | gem 'quiet_assets' 44 | gem 'web-console','~> 2.0' 45 | end 46 | 47 | # Use ActiveModel has_secure_password 48 | # gem 'bcrypt', '~> 3.1.7' 49 | 50 | # Use Unicorn as the app server 51 | # gem 'unicorn' 52 | gem 'puma' 53 | 54 | # Use Capistrano for deployment 55 | # gem 'capistrano-rails', group: :development 56 | 57 | group :development, :test do 58 | gem 'minitest-reporters' 59 | gem 'pry' 60 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 61 | gem 'byebug' 62 | 63 | # Access an IRB console on exception pages or by using <%= console %> in views 64 | 65 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 66 | gem 'spring' 67 | end 68 | 69 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: codemy/ruby:2.3.1 3 | commands: 4 | - gem update bundler 5 | - bundle install --path vendor/bundle 6 | - bundle exec rake db:create db:schema:load 7 | - bundle exec rake test 8 | 9 | environment: 10 | RACK_ENV: test 11 | RAILS_ENV: test 12 | SECRET_KEY_BASE: blahblahblah 13 | 14 | compose: 15 | database: 16 | image: postgres:9.5.1 17 | redis: 18 | image: redis:3.0.7 19 | elasticsearch: 20 | image: elasticsearch:2.2.0 21 | 22 | cache: 23 | mount: 24 | - vendor/bundle 25 | - .git 26 | 27 | publish: 28 | docker: 29 | storage_driver: overlay 30 | username: zacksiri 31 | password: $$DOCKER_HUB_PASSWORD 32 | email: zack@codemy.net 33 | repo: codemy/moviedb 34 | tag: latest 35 | when: 36 | branch: master 37 | 38 | docker: 39 | storage_driver: overlay 40 | username: zacksiri 41 | password: $$DOCKER_HUB_PASSWORD 42 | email: zack@codemy.net 43 | repo: codemy/moviedb 44 | tag: $$TAG 45 | when: 46 | event: tag 47 | 48 | deploy: 49 | rancher: 50 | url: http://139.162.43.181:8080/v1/projects/1a5 51 | access_key: 331394D5CCCEA7E2BE53 52 | secret_key: 6ESn1FhSsK7ptTTLnSyS9LT11RCyQKAgEaWr8pDL 53 | service: moviedb/web 54 | docker_image: codemy/moviedb:latest 55 | when: 56 | branch: master 57 | 58 | rancher: 59 | url: http://139.162.43.181:8080/v1/projects/1a5 60 | access_key: 331394D5CCCEA7E2BE53 61 | secret_key: 6ESn1FhSsK7ptTTLnSyS9LT11RCyQKAgEaWr8pDL 62 | service: moviedb/worker 63 | docker_image: codemy/moviedb:latest 64 | when: 65 | branch: master 66 | 67 | rancher: 68 | url: http://139.162.43.181:8080/v1/projects/1a27 69 | access_key: 11DA23F40759A1A305F5 70 | secret_key: xvidTFM5aKdFVFkBBgQvbiYqMcS99NR1eUTZAJG1 71 | service: moviedb/web 72 | docker_image: codemy/moviedb:$$TAG 73 | when: 74 | event: tag 75 | 76 | rancher: 77 | url: http://139.162.43.181:8080/v1/projects/1a27 78 | access_key: 11DA23F40759A1A305F5 79 | secret_key: xvidTFM5aKdFVFkBBgQvbiYqMcS99NR1eUTZAJG1 80 | service: moviedb/worker 81 | docker_image: codemy/moviedb:$$TAG 82 | when: 83 | event: tag 84 | 85 | -------------------------------------------------------------------------------- /app/models/movie.rb: -------------------------------------------------------------------------------- 1 | class Movie < ActiveRecord::Base 2 | include Elasticsearch::Model 3 | # we don't need the line below because we're 4 | # implementing our own 5 | # include Elasticsearch::Model::Callbacks 6 | 7 | after_commit :index_document, on: [:create, :update] 8 | after_commit :delete_document, on: :destroy 9 | 10 | def index_document 11 | IndexerJob.perform_later('index', self.id) 12 | end 13 | 14 | def delete_document 15 | IndexerJob.perform_later('delete', self.id) 16 | end 17 | 18 | validates :name, uniqueness: true 19 | 20 | has_and_belongs_to_many :genres 21 | 22 | has_many :roles 23 | has_many :crews, through: :roles 24 | 25 | mapping do 26 | indexes :id, index: :not_analyzed 27 | indexes :name 28 | indexes :synopsis 29 | indexes :year 30 | indexes :language 31 | indexes :country 32 | indexes :runtime, type: 'integer' 33 | indexes :review, type: 'float' 34 | indexes :crews, type: 'nested' do 35 | indexes :id, type: 'integer' 36 | indexes :name, type: 'string', index: :not_analyzed 37 | end 38 | indexes :genres, type: 'nested' do 39 | indexes :id, type: 'integer' 40 | indexes :name, type: 'string', index: :not_analyzed 41 | end 42 | end 43 | 44 | def as_indexed_json(options = {}) 45 | self.as_json(only: [:id, :name, :synopsis, :year, :country, :language, :runtime, :review], 46 | include: { 47 | crews: { only: [:id, :name] }, 48 | genres: { only: [:id, :name] } 49 | }) 50 | end 51 | 52 | 53 | class << self 54 | def custom_search(query_segment) 55 | # { "keyword" => "Terminator", "crews" => "1,27", "genres" => "2332, 2323"} 56 | keyword = query_segment.delete("keyword") 57 | filter_segments = query_segment 58 | 59 | __elasticsearch__.search(query: MoviesQuery.build(keyword), 60 | aggs: MoviesQuery::Aggregate.build, 61 | filter: MoviesQuery::Filter.build(filter_segments)) 62 | end 63 | end 64 | 65 | class RelationError < StandardError 66 | def initialize(msg = "That Relationship Type doesn't exist") 67 | super(msg) 68 | end 69 | end 70 | 71 | def add_many(type, data) 72 | if type.in? ['Genre', 'Crew'] 73 | # movie.genres = [data] 74 | self.send("#{type.downcase.pluralize}=", data.map do |g| 75 | type.classify.constantize.where(name: g).first_or_create! 76 | end) 77 | else 78 | raise RelationError 79 | end 80 | end 81 | 82 | end 83 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20150501104039) do 15 | 16 | # These are extensions that must be enabled in order to support this database 17 | enable_extension "plpgsql" 18 | enable_extension "hstore" 19 | 20 | create_table "crews", force: :cascade do |t| 21 | t.string "name" 22 | t.datetime "created_at", null: false 23 | t.datetime "updated_at", null: false 24 | end 25 | 26 | create_table "genres", force: :cascade do |t| 27 | t.string "name" 28 | t.datetime "created_at", null: false 29 | t.datetime "updated_at", null: false 30 | end 31 | 32 | create_table "genres_movies", id: false, force: :cascade do |t| 33 | t.integer "genre_id" 34 | t.integer "movie_id" 35 | end 36 | 37 | add_index "genres_movies", ["genre_id"], name: "index_genres_movies_on_genre_id", using: :btree 38 | add_index "genres_movies", ["movie_id"], name: "index_genres_movies_on_movie_id", using: :btree 39 | 40 | create_table "movies", force: :cascade do |t| 41 | t.string "name" 42 | t.text "synopsis" 43 | t.datetime "created_at", null: false 44 | t.datetime "updated_at", null: false 45 | t.string "country" 46 | t.integer "year" 47 | t.float "review" 48 | t.string "rating" 49 | t.integer "runtime" 50 | t.string "language" 51 | t.date "release_date" 52 | end 53 | 54 | create_table "roles", force: :cascade do |t| 55 | t.integer "movie_id" 56 | t.integer "crew_id" 57 | t.string "job" 58 | t.datetime "created_at", null: false 59 | t.datetime "updated_at", null: false 60 | end 61 | 62 | add_index "roles", ["crew_id"], name: "index_roles_on_crew_id", using: :btree 63 | add_index "roles", ["movie_id"], name: "index_roles_on_movie_id", using: :btree 64 | 65 | add_foreign_key "roles", "crews" 66 | add_foreign_key "roles", "movies" 67 | end 68 | -------------------------------------------------------------------------------- /config/database.yml.example: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 8.2 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On OS X with Homebrew: 6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config 7 | # On OS X with MacPorts: 8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 9 | # On Windows: 10 | # gem install pg 11 | # Choose the win32 build. 12 | # Install PostgreSQL and put its /bin directory on your path. 13 | # 14 | # Configure Using Gemfile 15 | # gem 'pg' 16 | # 17 | default: &default 18 | adapter: postgresql 19 | encoding: unicode 20 | username: postgres 21 | host: localhost 22 | # For details on connection pooling, see rails configuration guide 23 | # http://guides.rubyonrails.org/configuring.html#database-pooling 24 | pool: 10 25 | 26 | development: 27 | <<: *default 28 | database: moviedb_development 29 | 30 | # The specified database role being used to connect to postgres. 31 | # To create additional roles in postgres see `$ createuser --help`. 32 | # When left blank, postgres will use the default role. This is 33 | # the same name as the operating system user that initialized the database. 34 | #username: moviedb 35 | 36 | # The password associated with the postgres role (username). 37 | #password: 38 | 39 | # Connect on a TCP socket. Omitted by default since the client uses a 40 | # domain socket that doesn't need configuration. Windows does not have 41 | # domain sockets, so uncomment these lines. 42 | #host: localhost 43 | 44 | # The TCP port the server listens on. Defaults to 5432. 45 | # If your server runs on a different port number, change accordingly. 46 | #port: 5432 47 | 48 | # Schema search path. The server defaults to $user,public 49 | #schema_search_path: myapp,sharedapp,public 50 | 51 | # Minimum log levels, in increasing order: 52 | # debug5, debug4, debug3, debug2, debug1, 53 | # log, notice, warning, error, fatal, and panic 54 | # Defaults to warning. 55 | #min_messages: notice 56 | 57 | # Warning: The database defined as "test" will be erased and 58 | # re-generated from your development database when you run "rake". 59 | # Do not set this db to the same as development or production. 60 | test: 61 | <<: *default 62 | database: moviedb_test 63 | 64 | # As with config/secrets.yml, you never want to store sensitive information, 65 | # like your database password, in your source code. If your source code is 66 | # ever seen by anyone, they now have access to your database. 67 | # 68 | # Instead, provide the password as a unix environment variable when you boot 69 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database 70 | # for a full rundown on how to provide these environment variables in a 71 | # production deployment. 72 | # 73 | # On Heroku and other platform providers, you may have a full connection URL 74 | # available as an environment variable. For example: 75 | # 76 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" 77 | # 78 | # You can use this database configuration with: 79 | # 80 | # production: 81 | # url: <%= ENV['DATABASE_URL'] %> 82 | # 83 | production: 84 | <<: *default 85 | database: moviedb_production 86 | username: moviedb 87 | password: <%= ENV['MOVIEDB_DATABASE_PASSWORD'] %> -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 8.2 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On OS X with Homebrew: 6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config 7 | # On OS X with MacPorts: 8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 9 | # On Windows: 10 | # gem install pg 11 | # Choose the win32 build. 12 | # Install PostgreSQL and put its /bin directory on your path. 13 | # 14 | # Configure Using Gemfile 15 | # gem 'pg' 16 | # 17 | default: &default 18 | adapter: postgresql 19 | encoding: unicode 20 | username: postgres 21 | host: localhost 22 | port: 5432 23 | # For details on connection pooling, see rails configuration guide 24 | # http://guides.rubyonrails.org/configuring.html#database-pooling 25 | pool: 10 26 | 27 | development: 28 | <<: *default 29 | database: moviedb_development 30 | 31 | # The specified database role being used to connect to postgres. 32 | # To create additional roles in postgres see `$ createuser --help`. 33 | # When left blank, postgres will use the default role. This is 34 | # the same name as the operating system user that initialized the database. 35 | #username: moviedb 36 | 37 | # The password associated with the postgres role (username). 38 | #password: 39 | 40 | # Connect on a TCP socket. Omitted by default since the client uses a 41 | # domain socket that doesn't need configuration. Windows does not have 42 | # domain sockets, so uncomment these lines. 43 | #host: localhost 44 | 45 | # The TCP port the server listens on. Defaults to 5432. 46 | # If your server runs on a different port number, change accordingly. 47 | #port: 5432 48 | 49 | # Schema search path. The server defaults to $user,public 50 | #schema_search_path: myapp,sharedapp,public 51 | 52 | # Minimum log levels, in increasing order: 53 | # debug5, debug4, debug3, debug2, debug1, 54 | # log, notice, warning, error, fatal, and panic 55 | # Defaults to warning. 56 | #min_messages: notice 57 | 58 | # Warning: The database defined as "test" will be erased and 59 | # re-generated from your development database when you run "rake". 60 | # Do not set this db to the same as development or production. 61 | test: 62 | <<: *default 63 | database: moviedb_test 64 | 65 | # As with config/secrets.yml, you never want to store sensitive information, 66 | # like your database password, in your source code. If your source code is 67 | # ever seen by anyone, they now have access to your database. 68 | # 69 | # Instead, provide the password as a unix environment variable when you boot 70 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database 71 | # for a full rundown on how to provide these environment variables in a 72 | # production deployment. 73 | # 74 | # On Heroku and other platform providers, you may have a full connection URL 75 | # available as an environment variable. For example: 76 | # 77 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" 78 | # 79 | # You can use this database configuration with: 80 | # 81 | # production: 82 | # url: <%= ENV['DATABASE_URL'] %> 83 | # 84 | production: 85 | <<: *default 86 | host: <%= ENV['DB_HOST'] %> 87 | adapter: <%= ENV['DB_ADAPTER'] || 'postgresql' %> 88 | database: <%= ENV['DB_NAME'] %> 89 | username: <%= ENV['DB_USER'] %> 90 | password: <%= ENV['DB_PASSWORD'] %> -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = true 26 | 27 | # Compress JavaScripts and CSS. 28 | config.assets.js_compressor = :uglifier 29 | # config.assets.css_compressor = :sass 30 | 31 | # Do not fallback to assets pipeline if a precompiled asset is missed. 32 | config.assets.compile = false 33 | 34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 35 | # yet still be able to expire them through the digest params. 36 | config.assets.digest = true 37 | 38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 39 | 40 | # Specifies the header that your server uses for sending files. 41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | # config.log_tags = [ :subdomain, :uuid ] 53 | 54 | # Use a different logger for distributed setups. 55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 56 | 57 | # Use a different cache store in production. 58 | # config.cache_store = :mem_cache_store 59 | 60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 61 | # config.action_controller.asset_host = 'http://assets.example.com' 62 | 63 | # Ignore bad email addresses and do not raise email delivery errors. 64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 65 | # config.action_mailer.raise_delivery_errors = false 66 | 67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 68 | # the I18n.default_locale when a translation cannot be found). 69 | config.i18n.fallbacks = true 70 | 71 | # Send deprecation notices to registered listeners. 72 | config.active_support.deprecation = :notify 73 | 74 | # Use default logging formatter so that PID and timestamp are not suppressed. 75 | config.log_formatter = ::Logger::Formatter.new 76 | 77 | # Do not dump schema after migrations. 78 | config.active_record.dump_schema_after_migration = false 79 | end 80 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actionmailer (4.2.6) 5 | actionpack (= 4.2.6) 6 | actionview (= 4.2.6) 7 | activejob (= 4.2.6) 8 | mail (~> 2.5, >= 2.5.4) 9 | rails-dom-testing (~> 1.0, >= 1.0.5) 10 | actionpack (4.2.6) 11 | actionview (= 4.2.6) 12 | activesupport (= 4.2.6) 13 | rack (~> 1.6) 14 | rack-test (~> 0.6.2) 15 | rails-dom-testing (~> 1.0, >= 1.0.5) 16 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 17 | actionview (4.2.6) 18 | activesupport (= 4.2.6) 19 | builder (~> 3.1) 20 | erubis (~> 2.7.0) 21 | rails-dom-testing (~> 1.0, >= 1.0.5) 22 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 23 | activejob (4.2.6) 24 | activesupport (= 4.2.6) 25 | globalid (>= 0.3.0) 26 | activemodel (4.2.6) 27 | activesupport (= 4.2.6) 28 | builder (~> 3.1) 29 | activerecord (4.2.6) 30 | activemodel (= 4.2.6) 31 | activesupport (= 4.2.6) 32 | arel (~> 6.0) 33 | activerecord-nulldb-adapter (0.3.2) 34 | activerecord (>= 2.0.0) 35 | activesupport (4.2.6) 36 | i18n (~> 0.7) 37 | json (~> 1.7, >= 1.7.7) 38 | minitest (~> 5.1) 39 | thread_safe (~> 0.3, >= 0.3.4) 40 | tzinfo (~> 1.1) 41 | ansi (1.5.0) 42 | arel (6.0.3) 43 | autoprefixer-rails (6.3.7) 44 | execjs 45 | binding_of_caller (0.7.2) 46 | debug_inspector (>= 0.0.1) 47 | bootstrap-sass (3.3.6) 48 | autoprefixer-rails (>= 5.2.1) 49 | sass (>= 3.3.4) 50 | builder (3.2.2) 51 | byebug (9.0.5) 52 | coderay (1.1.1) 53 | coffee-rails (4.1.1) 54 | coffee-script (>= 2.2.0) 55 | railties (>= 4.0.0, < 5.1.x) 56 | coffee-script (2.4.1) 57 | coffee-script-source 58 | execjs 59 | coffee-script-source (1.10.0) 60 | concurrent-ruby (1.0.2) 61 | connection_pool (2.2.0) 62 | debug_inspector (0.0.2) 63 | elasticsearch (1.0.18) 64 | elasticsearch-api (= 1.0.18) 65 | elasticsearch-transport (= 1.0.18) 66 | elasticsearch-api (1.0.18) 67 | multi_json 68 | elasticsearch-model (0.1.9) 69 | activesupport (> 3) 70 | elasticsearch (> 0.4) 71 | hashie 72 | elasticsearch-rails (0.1.9) 73 | elasticsearch-transport (1.0.18) 74 | faraday 75 | multi_json 76 | erubis (2.7.0) 77 | execjs (2.7.0) 78 | faraday (0.9.2) 79 | multipart-post (>= 1.2, < 3) 80 | globalid (0.3.6) 81 | activesupport (>= 4.1.0) 82 | hashie (3.4.4) 83 | i18n (0.7.0) 84 | jbuilder (2.5.0) 85 | activesupport (>= 3.0.0, < 5.1) 86 | multi_json (~> 1.2) 87 | jquery-rails (4.1.1) 88 | rails-dom-testing (>= 1, < 3) 89 | railties (>= 4.2.0) 90 | thor (>= 0.14, < 2.0) 91 | json (1.8.3) 92 | loofah (2.0.3) 93 | nokogiri (>= 1.5.9) 94 | mail (2.6.4) 95 | mime-types (>= 1.16, < 4) 96 | method_source (0.8.2) 97 | mime-types (3.1) 98 | mime-types-data (~> 3.2015) 99 | mime-types-data (3.2016.0521) 100 | mini_portile2 (2.1.0) 101 | minitest (5.9.0) 102 | minitest-reporters (1.1.10) 103 | ansi 104 | builder 105 | minitest (>= 5.0) 106 | ruby-progressbar 107 | multi_json (1.12.1) 108 | multipart-post (2.0.0) 109 | nokogiri (1.6.8) 110 | mini_portile2 (~> 2.1.0) 111 | pkg-config (~> 1.1.7) 112 | pg (0.18.4) 113 | pkg-config (1.1.7) 114 | pry (0.10.4) 115 | coderay (~> 1.1.0) 116 | method_source (~> 0.8.1) 117 | slop (~> 3.4) 118 | puma (3.4.0) 119 | quiet_assets (1.1.0) 120 | railties (>= 3.1, < 5.0) 121 | rack (1.6.4) 122 | rack-protection (1.5.3) 123 | rack 124 | rack-test (0.6.3) 125 | rack (>= 1.0) 126 | rails (4.2.6) 127 | actionmailer (= 4.2.6) 128 | actionpack (= 4.2.6) 129 | actionview (= 4.2.6) 130 | activejob (= 4.2.6) 131 | activemodel (= 4.2.6) 132 | activerecord (= 4.2.6) 133 | activesupport (= 4.2.6) 134 | bundler (>= 1.3.0, < 2.0) 135 | railties (= 4.2.6) 136 | sprockets-rails 137 | rails-deprecated_sanitizer (1.0.3) 138 | activesupport (>= 4.2.0.alpha) 139 | rails-dom-testing (1.0.7) 140 | activesupport (>= 4.2.0.beta, < 5.0) 141 | nokogiri (~> 1.6.0) 142 | rails-deprecated_sanitizer (>= 1.0.1) 143 | rails-html-sanitizer (1.0.3) 144 | loofah (~> 2.0) 145 | railties (4.2.6) 146 | actionpack (= 4.2.6) 147 | activesupport (= 4.2.6) 148 | rake (>= 0.8.7) 149 | thor (>= 0.18.1, < 2.0) 150 | rake (11.2.2) 151 | rdoc (4.2.2) 152 | json (~> 1.4) 153 | redis (3.3.0) 154 | redis-namespace (1.5.2) 155 | redis (~> 3.0, >= 3.0.4) 156 | refiner (1.0.2) 157 | ruby-progressbar (1.8.1) 158 | sass (3.4.22) 159 | sass-rails (5.0.5) 160 | railties (>= 4.0.0, < 6) 161 | sass (~> 3.1) 162 | sprockets (>= 2.8, < 4.0) 163 | sprockets-rails (>= 2.0, < 4.0) 164 | tilt (>= 1.1, < 3) 165 | sdoc (0.4.1) 166 | json (~> 1.7, >= 1.7.7) 167 | rdoc (~> 4.0) 168 | sequel (4.36.0) 169 | sidekiq (4.1.4) 170 | concurrent-ruby (~> 1.0) 171 | connection_pool (~> 2.2, >= 2.2.0) 172 | redis (~> 3.2, >= 3.2.1) 173 | sinatra (>= 1.4.7) 174 | sinatra (1.4.7) 175 | rack (~> 1.5) 176 | rack-protection (~> 1.4) 177 | tilt (>= 1.3, < 3) 178 | slop (3.6.0) 179 | spring (1.7.2) 180 | sprockets (3.6.3) 181 | concurrent-ruby (~> 1.0) 182 | rack (> 1, < 3) 183 | sprockets-rails (3.1.1) 184 | actionpack (>= 4.0) 185 | activesupport (>= 4.0) 186 | sprockets (>= 3.0.0) 187 | thor (0.19.1) 188 | thread_safe (0.3.5) 189 | tilt (2.0.5) 190 | turbolinks (5.0.0) 191 | turbolinks-source (~> 5) 192 | turbolinks-source (5.0.0) 193 | tzinfo (1.2.2) 194 | thread_safe (~> 0.1) 195 | uglifier (3.0.0) 196 | execjs (>= 0.3.0, < 3) 197 | web-console (2.3.0) 198 | activemodel (>= 4.0) 199 | binding_of_caller (>= 0.7.2) 200 | railties (>= 4.0) 201 | sprockets-rails (>= 2.0, < 4.0) 202 | 203 | PLATFORMS 204 | ruby 205 | 206 | DEPENDENCIES 207 | activerecord-nulldb-adapter 208 | bootstrap-sass 209 | byebug 210 | coffee-rails (~> 4.1.0) 211 | elasticsearch-model 212 | elasticsearch-rails 213 | jbuilder (~> 2.0) 214 | jquery-rails 215 | minitest-reporters 216 | pg 217 | pry 218 | puma 219 | quiet_assets 220 | rails (= 4.2.6) 221 | redis 222 | redis-namespace 223 | refiner 224 | sass-rails (~> 5.0) 225 | sdoc (~> 0.4.0) 226 | sequel 227 | sidekiq 228 | spring 229 | turbolinks 230 | uglifier (>= 1.3.0) 231 | web-console (~> 2.0) 232 | 233 | RUBY VERSION 234 | ruby 2.3.1p112 235 | 236 | BUNDLED WITH 237 | 1.12.3 238 | --------------------------------------------------------------------------------