1 of 112

👩‍💻

Pushing the Boundaries with ActiveStorage

Andrea Fomera - Rails World 2024

2 of 112

3 of 112

Today we’ll cover

  • Using ActiveStorage with third-party services

4 of 112

Today we’ll cover

  • Using ActiveStorage with third-party services
  • Building a comprehensive Media Library

5 of 112

Hello, I’m Andrea Fomera 👋

  • Pronouns: she/her

6 of 112

Hello, I’m Andrea Fomera 👋

  • Pronouns: she/her
  • Senior Software Engineer at Soundstripe

7 of 112

Hello, I’m Andrea Fomera 👋

  • Pronouns: she/her
  • Senior Software Engineer at Soundstripe
  • https://afomera.dev

8 of 112

Hello, I’m Andrea Fomera 👋

  • Pronouns: she/her
  • Senior Software Engineer at Soundstripe
  • https://afomera.dev
  • @afomera everywhere that matters

9 of 112

Before we get started

  • My slides move fast
  • There will be a link to the code and slides at the end

10 of 112

Everything written for this talk

11 of 112

Let’s talk about ActiveStorage

12 of 112

“Active Storage facilitates uploading files to a cloud storage service like Amazon S3, Google Cloud Storage, or Microsoft Azure Storage and attaching those files to Active Record objects. It comes with a local disk-based service for development and testing and supports mirroring files to subordinate services for backups and migrations.”

13 of 112

ActiveStorage Simplifies File Uploads

14 of 112

ActiveStorage’s Core Tables

15 of 112

active_storage_blobs

Attribute

Type

key

String

filename

String

metadata

Text

service_name

String

byte_size

BigInt

checksum

String

created_at

DateTime

16 of 112

active_storage_attachments

Attribute

Type

name

String

record_type

String

record_id

BigInt

created_at

DateTime

17 of 112

active_storage_variant_records

Attribute

Type

blob_id

BigInt

variation_digest

String

* used only if you have track_variants enabled

18 of 112

How’s this work in practice?

19 of 112

How’s this work in practice?

20 of 112

Can we be more efficient?

21 of 112

Media Library to the Rescue

22 of 112

Building Custom Services with ActiveStorage

23 of 112

Create your own Service

24 of 112

Requirements for your own Service

25 of 112

26 of 112

27 of 112

28 of 112

29 of 112

Let’s implement Wistia as a Service

30 of 112

31 of 112

32 of 112

Handling Uploads

33 of 112

LET’S BREAK ALL THE RULES.

34 of 112

35 of 112

Let’s… push the boundaries

36 of 112

wistia:hashed_id:file_name

37 of 112

Introducing ActiveStorage::Providers

38 of 112

What is a provider?

39 of 112

Developer API

40 of 112

Developer API

41 of 112

Developer API

42 of 112

Implementation

43 of 112

44 of 112

45 of 112

providers_for class method

46 of 112

47 of 112

48 of 112

49 of 112

50 of 112

51 of 112

Recap of ActiveStorage Providers

52 of 112

You can define multiple providers…

53 of 112

Product Owners introduce new Requirements

54 of 112

Product Owners introduce new Requirements

55 of 112

Let’s extend add_provider_hooks

56 of 112

57 of 112

58 of 112

59 of 112

60 of 112

Frontend for Pexels

61 of 112

Demo Video 1

62 of 112

How do we implement this?

63 of 112

64 of 112

1. Custom Form Builder

65 of 112

66 of 112

2. Single Image Uploader View

67 of 112

2. Single Image Uploader View

68 of 112

3. PexelsController

69 of 112

70 of 112

4. Displaying & Selecting an Image

71 of 112

pexels:photoURL

72 of 112

Some Thoughts

73 of 112

Providers are Reusable!

74 of 112

Building a Media Library

75 of 112

First a demo video

76 of 112

77 of 112

This code may not be production ready.

78 of 112

ActiveStorage Schema (revisited!)

79 of 112

ActiveStorage Schema (revisited!)

80 of 112

Adding a User Reference

81 of 112

Adding a User Reference

82 of 112

83 of 112

Minimum Viable Product approach

84 of 112

Minimum Viable Product approach

85 of 112

86 of 112

87 of 112

Benefits of this approach

88 of 112

Benefits of this approach

89 of 112

Querying a User’s blobs

90 of 112

91 of 112

92 of 112

Leverage what Rails provides

93 of 112

It’s Expandable

94 of 112

95 of 112

Selecting from the Media Library just uses the existing Blob

96 of 112

Using ActiveStorage at Scale

97 of 112

Searching / Filtering

98 of 112

Extending ActiveStorage::Blob

99 of 112

100 of 112

101 of 112

102 of 112

Well Known Blobs

103 of 112

Preventing Deletion on Staging / QA

104 of 112

(Override the delete method and include the Blob when on staging)

105 of 112

Things to know

106 of 112

Set Current.user in Background Jobs / Rake Tasks

107 of 112

Enable providers on the has_one_attached association

108 of 112

Takeaways

109 of 112

Think outside the boundaries

110 of 112

Custom Services can allow you to do unique and new things

111 of 112

Thank you for your time

112 of 112

Slides / Code