Boilerplate uri = URI('http: //example.com/index.json') params = { limit: 10, page: 3 } uri.query = URI.encode_ www_form(params) req = Net ::HTTP ::Get.new uri req.basic_auth 'user', 'pass' res = Net ::HTTP.start(uri.host, uri.port) do |http| http.request(req) end if res.is_a?(Net ::HTTPSuccess) puts JSON.parse(res.body) end
Sensible Defaults class Post < ActiveRecord ::Base # in the world with no sensible defaults self.table_name = "posts" belongs_to :user, foreign_key: :user_id, class_name: "User", primary_key: :id end
Sensible Config module Web class Application < Hanami ::Application configure do root __dir __ routes 'config/routes' end end end “Who ever changed root? Who ever placed routes under another path? We're creating noise for the 99% of the developers who don't need these settings.” –Luca Gaudi https://discourse.hanamirb.org/t/hanami-2-0-ideas/306
Least Surprise # Load entity through API Amorail ::Lead.find ANY_NONEXISTENT_ID => false # why false? we're looking for an object, # nil makes more sense when nothing is found https://github.com/teachbase/amorail/issues/25
Case: Dry-Types require 'dry-struct' module Types include Dry ::Types.module end class User < Dry ::Struct attribute :name, Types ::String.optional attribute :age, Types ::Coercible ::Int end
Meaningful Errors def create_applicant api.applicant.create(params) rescue Onfido ::RequestError => e # What kind of error it is? # authentication, validation, whatever? end
Meaningful Errors def create_applicant api.applicant.create(params) rescue Onfido ::RequestError => e # What kind of error it is? # authentication, validation, whatever? end
Warnings if defined?( ::Rails) && !Rails.env.test? puts("******************************") puts("WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.") puts("******************************") end
Refinements module Anyway ::HashExt refine Hash do def stringify_keys! keys.each do |key| val = delete(key) val.stringify_keys! if val.is_a?(Hash) self[key.to_s] = val end end end end https://github.com/palkan/anyway_config
Adapterization # config/application.rb module YourApp class Application < Rails ::Application config.active_job.queue_adapter = :sidekiq end end • Active Job
Extensibility Sidekiq.configure_server do |config| config.server_middleware do |chain| chain.add Sidekiq ::OinkMiddleware, logger: :new_relic end end • Sidekiq
• Custom matchers/assertions Testability # Pundit it "grants access if post is published" do expect(subject).to permit(admin, post) end # ActiveModelSerializers test "should render post serializer" do get :index assert_serializer "PostSerializer" end
• Test helpers / mocking Testability # Devise test "should be success" do sign_in user get :index assert_equal 200, response.status end # Fog Fog.mock!
• Test mode/configuration Testability CarrierWave.configure do |config| config.enable_processing = false end Devise.setup do |config| config.stretches = Rails.env.test? ? 1 : 11 end Sidekiq ::Testing.fake!
Case: EvilClient let(:client) { double('client') } let(:candidates) do double('candidates').tap do |stub| allow(client).to receive(:candidates).and_return(stub) end end before do expect(integration).to receive(:client).and_return(client) end it "creates checkr candidate" do expect(candidates).to receive(:create).with( a_hash_including(params).and_return(id: 'checkr-123') expect(subject.checkr_id).to eq 'checkr-123' end Before v1.1.0
Case: EvilClient before do stub_client_operation(CheckrClient, "candidates.create") .with(token: "foo", **params) .to_return(id: 'checkr-123') end it "creates checkr candidate" do expect(subject.checkr_id).to eq 'checkr-123' end Since v1.1.0
Case: Wrapper module Resolver class << self def resolve(host) return "1.2.3.4" if @test == true Resolv.getaddress(host) end def enable_test! @test = true end end end