require 's3_storage/null'

class S3Storage
  NotConfiguredError = Class.new(StandardError)

  def self.build(bucket_name)
    bucket_name.present? ? new(bucket_name) : Null.new
  end

  def initialize(bucket_name)
    @bucket_name = bucket_name
  end

  def save(asset, options = {})
    unless md5_from_metadata_for(asset) == asset.md5_hexdigest
      s3_options = { metadata: { 'md5-hexdigest' => asset.md5_hexdigest } }.merge(options)
      object_for(asset).upload_file(asset.file.path, s3_options)
    end
  end

  def presigned_url_for(asset, http_method: 'GET')
    object_for(asset).presigned_url(http_method, expires_in: 1.minute, virtual_host: AssetManager.aws_s3_use_virtual_host)
  end

private

  def object_for(asset)
    Aws::S3::Object.new(bucket_name: @bucket_name, key: asset.uuid)
  end

  def head_object_for(asset)
    client.head_object(bucket: @bucket_name, key: asset.uuid)
  end

  def md5_from_metadata_for(asset)
    result = head_object_for(asset)
    result.metadata['md5-hexdigest']
  rescue Aws::S3::Errors::NotFound
    nil
  end

  def client
    Aws::S3::Client.new
  end
end

require 's3_storage/null'

class S3Storage
  NotConfiguredError = Class.new(StandardError)

  def self.build(bucket_name)
    if bucket_name.present?
      new(bucket_name)
    else
      Null.new
    end
  end

  def initialize(bucket_name)
    @bucket_name = bucket_name
  end

  def save(asset, options = {})
    unless md5_from_metadata_for(asset) == asset.md5_hexdigest
      s3_options = { metadata: { 'md5-hexdigest' => asset.md5_hexdigest } }.merge(options)
      object_for(asset).upload_file(asset.file.path, s3_options)
    end
  end

  def presigned_url_for(asset, http_method: 'GET')
    object_for(asset).presigned_url(http_method, expires_in: 1.minute, virtual_host: AssetManager.aws_s3_use_virtual_host)
  end

private

  def object_for(asset)
    Aws::S3::Object.new(bucket_name: @bucket_name, key: asset.uuid)
  end

  def head_object_for(asset)
    client.head_object(bucket: @bucket_name, key: asset.uuid)
  end

  def md5_from_metadata_for(asset)
    result = head_object_for(asset)
    result.metadata['md5-hexdigest']
  rescue Aws::S3::Errors::NotFound
    nil
  end

  def client
    Aws::S3::Client.new
  end
end

Convert ternary expression into if/else in S3Storage.build
Convert ternary expression into if/else in S3Storage.build

I'm about to make this logic more complicated and I think it will be
easier to see the changes if I make this change first.
