About Rails concerns

Introduction

module Emailable
include ActiveSupport::Concern
def deliver(email)
# send email here...
end
end
class Document
include Emailable
def archive
@archived = true
deliver({to: 'me@mydomain.com', subject: 'Document archived', body: @content})
end
end

Concerns used wrong

Using Concerns to make the classes smaller

class Document
include Emailable, Storable, Erasable
def archive
@archived = true
deliver({to: 'me@mydomain.com', subject: 'Document archived', body: @content})
remove
end
end

Bi-directional dependencies

module Printable
include ActiveSupport::Concern
def print
raise UnknownFormatError unless ['pdf', 'doc'].include?(@format)
# do print @content
end
end
class Document
include Printable
def initialize(format, content)
@format = format
@content = content
end
def export
# ...
print
end
end
module Printable
include ActiveSupport::Concern
def print(format, content)
raise UnknownFormatError unless ['pdf', 'doc'].include?(format)
# do print content
end
end
class Document
include Printable
def initialize(format, content)
@format = format
@content = content
end
def export
# ...
print(@format, @content)
end
end

Triangular dependencies

module Connectable
include ActiveSupport::Concern
def connect_to(device)
# ...
end
end
module Printable
include ActiveSupport::Concern
def print(format, content)
connect_to(Printer::lookup)
# ...
end
end
class Document
include Connectable, Printable
def export
# ...
print(@format, @content)
end
def upload_to(remote_resource)
connect_to(remote_resource)
#...
end
end

Concerns used properly

Explicit is better than implicit

# Aggregation
class Document
def archive
@archived = true
Mailer.deliver({to: 'me@mydomain.com', subject: 'Document archived', body: @content})
Store.remove
end
end
# Composition
class Document
def initialize(mailer, store)
@mailer = mailer
@store = store
end
def archive
@archived = true
@mailer.deliver({to: 'me@mydomain.com', subject: 'Document archived', body: @content})
@store.remove
end
end

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Carles Climent

Carles Climent

More from Medium

Rails Today

Ruby and Ruby on Rails

Is Ruby on Rails worth learning today?

Off the Rails