
Security News
Package Maintainers Call for Improvements to GitHub’s New npm Security Plan
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
This gem is a Rails extension that enhances sorbet support in Rails.
Install the gem and add to the application's Gemfile by executing:
bundle add rails-on-sorbet
If bundler is not being used to manage dependencies, install the gem by executing:
gem install rails-on-sorbet
It is recommended to disable strict typechecking for this gem's RBI files generated by tapioca.
This can be done by adding these lines to sorbet/tapioca/config.yml
:
gem:
typed_overrides:
rails-on-sorbet: "false"
This gem adds additional signatures to Rails types and builtin Ruby types that make using sorbet easier in Rails projects.
It also adds some new utility types and modifies certain Rails DSLs to make it possible to strictly type methods defined through metaprogramming.
Rails and Ruby lack a unified type for representing datetime.
We have Time
, DateTime
and ActiveSupport::TimeWithZone
which basically
cover really similar use cases but have no common ancestor.
This makes working with time incredibly frustrating.
We introduced a new utility type called Timelike
to alleviate this burden.
Definition:
Timelike = T.type_alias { T.any(Time, DateTime, ActiveSupport::TimeWithZone) }
Rails introduced two hashlike types: ActionController::Parameters
, ActiveSupport::HashWithIndifferentAccess
.
For the most part they behave like Hash
but they don't inherit from it.
This causes a lot of issues in sorbet.
Because of that we introduced the Map
interface.
It defines all methods that are common to Hash
, ActionController::Parameters
and ActiveSupport::HashWithIndifferentAccess
.
Right now there is a bug in sorbet that causes the typechecker to hang and crash when you include a generic interface/module in Hash
, Array
, Set
, Range
etc.
So we couldn't implement Map
directly in Hash
:(
Instead, we introduced a casting function.
Example:
# Use the `Map` type in a signature
#
#: (Map[String, Integer]) -> void
def foo(m)
m["foo"] #=> Integer?
end
hash = { "foo" => 4 } #: Hash[String, Integer]
m = Map(hash) #=> Map[String, Integer]
foo(m) # OK
hash = { "foo" => 4 }.with_indifferent_access # => ActiveSupport::HashWithIndifferentAccess
m = Map(hash) #=> Map[String, untyped]
foo(m) # OK
params = ActionController::Parameters.new # => ActionController::Parameters
m = Map(params) #=> Map[String, untyped]
foo(m) # OK
This gem adds a new method called alias_association
on ActiveRecord classes.
It lets you define aliases for getters and setters of belongs_to
and has_one
associations. There is also a tapioca compiler that makes sorbet aware of these aliases.
Example:
class Foo < ApplicationRecord
belongs_to :user
alias_association :owner, :user
end
f = Foo.last
f.owner == f.user #=> true
This is a subclass of ActiveSupport::CurrentAttributes
with tapioca/sorbet support.
New optional keyword arguments have been added to attribute
:
type
: the sorbet type of the getter/setterdoc
: a docstring whose content will be used to generate a comment above the rbi signature created by tapiocaExample:
class Current < Rails::On::Sorbet::CurrentAttributes
attribute :session_counter, type: T.nilable(Integer), doc: <<~DOC
A counter that gets incremented when a new session is created.
DOC
end
The tapioca compiler will generate an RBI file like this:
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Current`.
# Please instead update this file by running `bin/tapioca dsl Current`.
class Current
include RailsOnSorbetCurrentAttributeMethods
extend RailsOnSorbetCurrentAttributeMethods
module RailsOnSorbetCurrentAttributeMethods
# A counter that gets incremented when a new session is created.
sig { returns(T.nilable(::Integer)) }
def session_counter; end
# A counter that gets incremented when a new session is created.
sig { params(value: T.nilable(::Integer)).returns(T.nilable(::Integer)) }
def session_counter=(value); end
end
end
Tapioca now has the ability to generate strictly typed and accurate getters and setters for Rails serializers.
New optional keyword arguments have been added to ActiveRecord::Base::serialize
:
return_type
: the sorbet type returned by the gettersetter_type
: the sorbet type of the parameter of the setterdoc
: a docstring whose content will be used to generate a comment above the rbi signature created by tapiocaIf no return_type
or setter_type
is given in the arguments, tapioca will try to call return_type
and setter_type
on the coder
given to the serializer.
Example:
module IntegerCoder
class << self
def return_type = Integer
#: (String?) -> Integer?
def load(val)
val&.to_i
end
#: (Integer?) -> String?
def dump(val)
val&.to_s
end
end
end
class Foo < ActiveRecord::Base
serialize :bar, coder: IntegerCoder
serialize :baz, coder: YAML, return_type: T::Hash[String, String], doc: <<~DOC
Additional BAR data for finalizing orders.
DOC
end
The tapioca compiler will generate the following RBI file
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Foo`.
# Please instead update this file by running `bin/tapioca dsl Foo`.
class Foo
sig { returns(T.nilable(Integer)) }
def bar; end
sig { params(value: T.nilable(Integer)).returns(T.nilable(Integer)) }
def bar=(value); end
# Additional BAR data for finalizing orders.
sig { returns(T.nilable(T::Hash[::String, ::String])) }
def baz; end
# Additional BAR data for finalizing orders.
sig { params(value: T.nilable(T::Hash[::String, ::String])).returns(T.nilable(T::Hash[::String, ::String])) }
def baz=(value); end
end
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/espago/rails-on-sorbet.
FAQs
Unknown package
We found that rails-on-sorbet demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.