Skip to content

Instantly share code, notes, and snippets.

@jfeaver
Last active September 30, 2022 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfeaver/d5de672f8578a13385bf4b9a251384b6 to your computer and use it in GitHub Desktop.
Save jfeaver/d5de672f8578a13385bf4b9a251384b6 to your computer and use it in GitHub Desktop.
Use Dry gems to build a struct which has an active record relation from a specified model as an attribute
require 'dry-struct'
require 'active_record'
module Types
include Dry.Types
def self.ArRelation(model_class)
# Note that ActiveRecord_Relation, ActiveRecord_Associations_CollectionProxy, and ActiveRecord_AssociationRelation
# are private constants - they may change some day
Instance(model_class.const_get(:ActiveRecord_Relation)) |
Instance(model_class.const_get(:ActiveRecord_Associations_CollectionProxy)) |
Instance(model_class.const_get(:ActiveRecord_AssociationRelation)) |
Array.of(Instance(model_class))
end
end
class Foo < ActiveRecord::Base; end
class Bar < ActiveRecord::Base; end
class Thing < Dry::Struct
attribute :foos, Types.ArRelation(Foo)
end
Thing.new(foos: Foo.none) # => A Thing!
Thing.new(foos: Bar.none) # => Dry::Struct::Error: [Thing.new] #<ActiveRecord::Relation []> (Bar::ActiveRecord_Relation) has invalid type for :foos ...
@pandwoter
Copy link

Great gist! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment