Sometimes I want to write a ruby script that uses the models or other things in the Rails application. The simplest way to do it is to write a little script and executes it with Rails script runner. But what if the script is more than a few lines of code and needs to be able to handle multiple arguments? Let’s say I want to build a thrift server that uses Rails models and put it under Rails.root/script folder:
#!/usr/bin/env ruby require 'optparse' # Default options app_config = { :environment => "development" } # Parses options OptionParser.new do |opts| opts.on("-e", "--environment=name", String, "Specifies the environment for the server to operate under (test/development/production).", "Default: development") { |v| app_config[:environment] = v } opts.on("-p", "--port=name", Integer, "Runs thrift server on the specific port.", "Default: 9090") { |v| app_config[:port] = v } end.parse! ENV["RAILS_ENV"] ||= app_config[:environment] STDOUT.sync = true # Loads Rails environment require File.expand_path('../../config/boot', __FILE__) require File.expand_path("../../config/environment", __FILE__) app_config = YAML::load(ERB.new(IO.read(File.join(Rails.root, 'config/app.yml'))).result)[Rails.env].with_indifferent_access.merge(app_config) port = app_config[:port] || 9090 thread_count = app_config[:thread] || 1 # Includes thrift-generated code $:.push("#{Rails.root}/app/thrift") class AppServiceHandler def initialize(options = {}) ... end ... end handler = AppServiceHandler.new(app_config) processor = AppService::Processor.new(handler) transport = Thrift::ServerSocket.new(port) transportFactory = Thrift::BufferedTransportFactory.new() protocolFactory = Thrift::BinaryProtocolFactory.new() server = Thrift::ThreadPoolServer.new(processor, transport, transportFactory, protocolFactory, thread_count) server.serve()