Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/errgonomic/rails/active_record_optional.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,18 @@ def to_option
end
end

module Errgonomic
module Option
# An Option is already lifted. Lifting it again would nest it, and the
# nesting is invisible until something reaches for the inner value.
class Any
def to_option
self
end
end
end
end

module Errgonomic
module Rails
# Teach ActiveRecord SQL quoting to unwrap Options, quoting a None as
Expand Down
20 changes: 20 additions & 0 deletions test/rails_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,26 @@ def test_nested_options_and_results_refuse_to_serialize
assert_raises(Errgonomic::SerializeError) { [Ok(5)].to_json }
end

# to_option lifts a value that may be nil. An Option is already lifted, and
# a second lift nests invisibly: Some(Some(x)) still answers some?, so the
# mistake surfaces far from where it was made.
def test_to_option_is_idempotent
assert_equal Some(1), Some(1).to_option
assert_equal 1, Some(1).to_option.unwrap!
assert None().to_option.none?
end

# The shape an application reaches for around an unwrapped association:
# lift it, then reach through it for an attribute that is already an Option.
def test_to_option_composes_through_an_unwrapped_association
author = Author.create!(name: 'Cixin Liu', bio: 'writes sci-fi')
shelved = Book.create!(title: 'The Dark Forest', author_id: author.id)
unshelved = Book.create!(title: 'Supernova Era')

assert_equal 'writes sci-fi', shelved.author.to_option.and_then(&:bio).unwrap_or('unknown')
assert_equal 'unknown', unshelved.author.to_option.and_then(&:bio).unwrap_or('unknown')
end

def test_delegate_optional
author = Author.create!(name: 'Cixin Liu')
book = author.books.create!(title: 'Death\'s End')
Expand Down
Loading