Sometimes, you want to convert from an ActiveRecord
model to something more akin to a simple data class. Enter Sorbet's T::Struct
. This gem helps to eject out of bulky ActiveRecord
models (or buckle into them) and work with simple T::Struct
's in the rest of your app.
For more information about the "why" behind this gem, check out this post.
Install the gem and add to the application's Gemfile by executing:
$ bundle add activerecord-ejection_seat
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install activerecord-ejection_seat
Let's say you have an ActiveRecord
model for a User
with a string name
column, an integer age
column, a role
enum column and a belongs to association with a Location
model. Another way to express this would be a User
type that is a simple, typed struct with other supporting structs.
module Types
class UserRoles < T::Enum
enums do
Admin = new("admin")
Member = new("member")
end
end
class Location < T::Struct
const :name, String
end
class User < T::Struct
const :name, String
const :age, Integer
const :role, UserRoles
const :location, Location
end
end
In our model, we can specify an ejection to this type.
class User
belongs_to :location
enum :role, { admin: "admin", member: "member" }
ejects_to Types::User
end
Now, we have two new methods available on User
. First, we can eject from a User
instance to a Types::User
.
location = Location.new(name: "Florida")
User.new(name: "Max", age: 28, role: "admin", location: location).eject
# => Types::User(name: "Max", age: 28, role: Types::UserRoles::Admin, location: Types::Location.new(name: "Florida))
User.new(name: "Max", age: 28, role: "admin", location: location).to_struct # alias
Second, we can buckle into the User
model with a Types::User
.
user_struct = Types::User.new(name: "Max", age: 28, role: Types::UserRoles::Admin, location: Types::Location.new(name: "Florida"))
User.buckle(user_struct)
# => User(name: "Max", age: 28, role: "admin", location: Location(name: "Florida"))
User.from_struct(user_struct) # alias
After checking out the repo, run bin/setup
to install dependencies. Then, run rake
to run Rubocop and the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment. You'll need a schema to test ActiveRecord
against. Check out spec/spec_helper.rb
for an example setup.
To install this gem onto your local machine, run bundle exec rake install
.
Bug reports and pull requests are welcome on GitHub at https://github.com/maxveldink/activerecord-ejection_seat. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in this project's codebase, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
I love creating in the open. If you find this or any other maxveld.ink content useful, please consider sponsoring me on GitHub.