Successfully reported this slideshow.
Your SlideShare is downloading. ×

Ruby w/o Rails (Олександр Сімонов)

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 25 Ad

Ruby w/o Rails (Олександр Сімонов)

Download to read offline

Доповідь про веб на Ruby без Rails, без "магії" та AR. Практичні приклади як зробити роботу без Rails зручнішою для Rails developer.

Доповідь про веб на Ruby без Rails, без "магії" та AR. Практичні приклади як зробити роботу без Rails зручнішою для Rails developer.

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Viewers also liked (20)

Advertisement

Similar to Ruby w/o Rails (Олександр Сімонов) (20)

More from Fwdays (20)

Advertisement

Recently uploaded (20)

Ruby w/o Rails (Олександр Сімонов)

  1. 1. Ruby w/o rails Oleksandr Simonov
  2. 2. About me • Name: Oleksandr Simonov • Occupation: Founder and Owner of Amoniac • Hobby: Open Source contribution • Github: @simonoff
  3. 3. Why Ruby w/o Rails? • Rails is a monolithic stone • Rails is slow • Rails force you to be a lazy
  4. 4. rails is: • activerecord • activemodel • activesupport • actionmailer • actionpack • actionview • activejob • railties
  5. 5. benchmark http://www.madebymarket.com/blog/dev/ruby-web- benchmark-report.html
  6. 6. Lazy Rails developer
  7. 7. Alternatives • Rack • Sinatra • Cuba • Grape (API) • Reel • Nahami • Sequel • ROM WEB ORM
  8. 8. Advantages • Faster then Rails • Less time for app loading • New knowledge
  9. 9. Disadvantages • No Rails like console • No Rails like code autoloading • No Rails helpers • No "Magic" • More code
  10. 10. Practical section • Download list of Finnish companies • Insert/Update local DB • On API call returns e-invoice address
  11. 11. - app - models - services - workers - config - boot.rb - initializers - 01-dotenv.rb - 02-airbrake.rb - 03-sequel.rb - 04-sidekiq.rb - db - migrations - init.rb - config.ru Structure
  12. 12. require 'rubygems' require 'bundler/setup' require_relative 'init' # Application code loading require 'sidekiq/web' use Rack::ContentLength use Rack::CommonLogger, ::NetvisorSpreadsheets. logger # use own logger use Rack::ShowExceptions run Rack::URLMap.new('/' => ::NetvisorSpreadsheets: :Server, '/sidekiq' => Sidekiq::Web) config.ru
  13. 13. init.rb # encoding: UTF-8 ENV['RACK_ENV'] ||= 'development' # default environment require 'rubygems' module NetvisorSpreadsheets # Singletone extend self attr_accessor :db def root # helper for get application root path @root_path ||= ::Pathname.new(::File.join(File.dirname(__FILE__))).expand_path end def env # helper for get environment @env ||= ENV["RACK_ENV"] || "development" end def logger # helper for logger @logger ||= ::Logger.new(self.root.join('log', "#{self.env}.log").to_s) end end ::NetvisorSpreadsheets.logger.level = if ::NetvisorSpreadsheets.env == 'production' ::Logger::INFO else ::Logger::DEBUG end # require boot file require self.root.join('config', 'boot.rb').to_s
  14. 14. $LOAD_PATH.unshift ::NetvisorSpreadsheets.root # add root path to load path # autoload some initializers, models, workers and services def load_folder(*path) ::Dir.glob(::NetvisorSpreadsheets.root.join(*path)).each { |r| require r } end load_folder('config', 'initializers', '**/*.rb') load_folder('app', 'models', '**/*.rb') load_folder('app', 'workers', '**/*.rb') load_folder('app', 'services', '**/*.rb') # require sinatra server code require 'config/server' boot.rb
  15. 15. source 'https://rubygems.org' gem 'sqlite3' gem 'dotenv' gem 'sequel' gem 'sinatra' gem 'sinatra-contrib' gem 'sidekiq' gem 'airbrake' gem 'puma' gem 'sidekiq-cron', '~> 0.3', require: false gem 'sidekiq-unique-jobs', '~> 4.0' Gemfile
  16. 16. require 'rubygems' require 'bundler/setup' require 'sequel' require 'dotenv' require 'rake' env = ENV['RACK_ENV'] || 'development' namespace :db do desc 'Run migrations' task :migrate, [:version] do |_t, args| ::Dotenv.load(".env", ".env.#{env}") ::Sequel.extension :migration db = ::Sequel.connect(::ENV.fetch('DATABASE_URL')) if args[:version] puts "Migrating to version #{args[:version]}" ::Sequel::Migrator.run(db, 'db/migrations', target: args[:version].to_i) else puts 'Migrating to latest' ::Sequel::Migrator.run(db, 'db/migrations') end end end Rakefile
  17. 17. ::Sequel.migration do transaction up do create_table :companies do primary_key :id String :company_id, null: false, index: true String :name, null: false String :einvoice_address, null: false String :einvoice_operator, null: false end end down do drop_table :companies end end db/migrations/001_create_companies.rb
  18. 18. class CompanyUpdaterWorker include ::Sidekiq::Worker sidekiq_options unique: :while_executing URL = "http://verkkolasku.tieke.fi/ExporVLOsoiteToExcel.aspx?type=csv" def perform path = ::Tempfile.new('vlo').path if http_download_uri(::URI.parse(URL), path) ::NetvisorSpreadsheets::CompaniesFillerService.new(path).import end end def http_download_uri(uri, filename) begin ::Net::HTTP.new(uri.host, uri.port).start do |http| http.request(Net::HTTP::Get.new(uri.request_uri)) do |response| ::File.open(filename, 'wb') do |io| response.read_body { |chunk| io.write(chunk) } end end end rescue Exception => e return false end true end end companies_updater_worker.rb
  19. 19. companies_filler_service.rb class CompanyUpdaterWorker include ::Sidekiq::Worker sidekiq_options unique: :while_executing URL = "http://verkkolasku.tieke.fi/ExporVLOsoiteToExcel.aspx?type=csv" def perform path = ::Tempfile.new('vlo').path if http_download_uri(::URI.parse(URL), path) ::NetvisorSpreadsheets::CompaniesFillerService.new(path).import end end def http_download_uri(uri, filename) begin ::Net::HTTP.new(uri.host, uri.port).start do |http| http.request(Net::HTTP::Get.new(uri.request_uri)) do |response| ::File.open(filename, 'wb') do |io| response.read_body { |chunk| io.write(chunk) } end end end rescue Exception => e return false end true end end
  20. 20. require 'sinatra/base' require 'sinatra/json' module NetvisorSpreadsheets class Server < Sinatra::Base configure :production, :development do enable :logging set :json_encoder, :to_json end get '/' do if params['company_id'] && params['company_id'].length > 0 json ::NetvisorSpreadsheets::CompanyFinderService.find(params['company_id']) else 400 end end end end server.rb
  21. 21. What we get? • Only 40Mb RAM • 1 second app load • Fast deployment
  22. 22. Questions

×