Create null objects for ActiveRecord models.
Install the gem and add to the application's Gemfile by executing:
$ bundle add activerecord-null
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install activerecord-null
Extend your primary abstract class with ActiveRecord::Null.
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
extend ActiveRecord::Null
endDefine a null object for the model.
class User < ApplicationRecord
has_many :posts
Null do
def name = "None"
end
endThis will create a Singleton class User::Null that mimics the User class.
Use the null object.
User.nullIt will even work with associations.
User.null.posts # => []By default, the null object will have the same attributes as the original model and will return nil for all attributes.
You can override this by passing a hash to the Null method where the key is an array of attributes and the value is the value to return for the attribute.
class User < ApplicationRecord
Null([:name, :team_name] => "Unknown") do
def other_attribute = "Other"
end
endYou may also pass a callable to the hash which will be used to determine the value for the attribute.
class User < ApplicationRecord
Null([:name, :team_name] => -> { "Unknown" })
endCustomize the null class name:
class User < ApplicationRecord
Null(class_name: "Guest")
class << self
alias_method :null, :guest
end
end
User.guest # returns a User::Guest instanceWhile Null objects are singletons (one instance per model), Void objects are instantiable null objects that allow creating multiple instances with different attribute values.
Define a void object for the model:
class Product < ApplicationRecord
Void([:name] => "Unknown Product") do
def display_name
"Product: #{name}"
end
end
endCreate instances with custom attributes:
product1 = Product.void(name: "Widget")
product2 = Product.void(name: "Gadget")
product1.name # => "Widget"
product2.name # => "Gadget"Each call to .void returns a new instance:
Product.void.object_id != Product.void.object_id # => trueInstance attributes override defaults:
product = Product.void(name: "Custom")
product.name # => "Custom" (overrides default "Unknown Product")
default_product = Product.void
default_product.name # => "Unknown Product" (uses default)Void objects support the same features as Null objects:
- Callable defaults (lambdas/procs)
- Custom methods via block syntax
- Association handling
- All ActiveRecord query methods (
null?,persisted?, etc.) - Custom class names via
class_name:parameter
class Product < ApplicationRecord
Void(class_name: "Placeholder")
class << self
alias_method :void, :placeholder
end
end
Product.placeholder # returns a Product::Placeholder instanceUse Null when you need a single shared null object instance. Use Void when you need multiple null object instances with different attribute values.
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.
Releases are automated via the shared release workflow. Trigger a release by running the "Release gem to RubyGems.org" workflow from the Actions tab.
This gem is managed with Reissue.
Bug reports and pull requests are welcome on GitHub at https://github.com/SOFware/activerecord-null.