Back to Repositories

Testing Field Attachments and Relationships in rails_admin

This test suite implements comprehensive field testing for a Rails Admin application, focusing on various file attachment handlers and model relationships. It validates multiple upload mechanisms including Paperclip, Dragonfly, CarrierWave, ActiveStorage, and Shrine, while also testing enum implementations and nested attributes.

Test Coverage Overview

The test suite provides extensive coverage of field relationships and file upload capabilities in Rails Admin. Key functionality includes:

  • Nested attributes testing for has_many and has_one relationships
  • Multiple file upload handler implementations
  • Enum field validations for both string and integer types
  • Rich text field integration testing

Implementation Analysis

The testing approach implements a comprehensive model structure that validates various Rails features and file upload gems. It utilizes ActiveRecord associations combined with multiple file upload solutions, demonstrating version-aware implementations for different Rails versions.

The pattern follows a modular approach with conditional logic for different Rails versions and optional features.

Technical Details

Testing tools and configurations include:

  • ActiveRecord as the ORM layer
  • Multiple file upload gems (Paperclip, Dragonfly, CarrierWave, Shrine)
  • ActiveStorage integration for modern Rails versions
  • ActionText for rich text handling
  • JSON serialization for multiple file uploads

Best Practices Demonstrated

The test implementation showcases several best practices:

  • Version-aware code implementation for different Rails versions
  • Proper cleanup handling for file attachments
  • Conditional feature loading based on framework availability
  • Comprehensive validation and callback implementation

railsadminteam/rails_admin

spec/dummy_app/app/active_record/field_test.rb

            
# frozen_string_literal: true

class FieldTest < ActiveRecord::Base
  has_many :nested_field_tests, dependent: :destroy, inverse_of: :field_test
  accepts_nested_attributes_for :nested_field_tests, allow_destroy: true

  has_one :comment, as: :commentable
  accepts_nested_attributes_for :comment, allow_destroy: true

  has_attached_file :paperclip_asset, styles: {thumb: '100x100>'}
  attr_accessor :delete_paperclip_asset

  before_validation { self.paperclip_asset = nil if delete_paperclip_asset == '1' }

  ActiveRecord::Base.extend Dragonfly::Model
  ActiveRecord::Base.extend Dragonfly::Model::Validations
  dragonfly_accessor :dragonfly_asset

  mount_uploader :carrierwave_asset, CarrierwaveUploader
  mount_uploaders :carrierwave_assets, CarrierwaveUploader
  if ActiveRecord.gem_version < Gem::Version.new('7.1')
    serialize :carrierwave_assets, JSON
  else
    serialize :carrierwave_assets, coder: JSON
  end

  if defined?(ActiveStorage)
    has_one_attached :active_storage_asset
    attr_accessor :remove_active_storage_asset

    after_save { active_storage_asset.purge if remove_active_storage_asset == '1' }

    has_many_attached :active_storage_assets
    attr_accessor :remove_active_storage_assets

    after_save do
      Array(remove_active_storage_assets).each { |id| active_storage_assets.find_by_id(id)&.purge }
    end
  end

  include ShrineUploader.attachment(:shrine_asset)
  include ShrineVersioningUploader.attachment(:shrine_versioning_asset)

  has_rich_text :action_text_field if defined?(ActionText)

  if ActiveRecord.gem_version >= Gem::Version.new('7.0')
    enum :string_enum_field, {S: 's', M: 'm', L: 'l'}
    enum :integer_enum_field, %i[small medium large]
  else
    enum string_enum_field: {S: 's', M: 'm', L: 'l'}
    enum integer_enum_field: %i[small medium large]
  end

  validates :string_field, exclusion: {in: ['Invalid']} # to test file upload caching
end