ActiveRecord::Null
Create null objects for ActiveRecord models.
Installation
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
Usage
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 instanceVoid Objects
While 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.
Development
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.
Releasing
Releases are automated via the shared release workflow. Trigger a release by running the "Release gem to RubyGems.org" workflow from the Actions tab.
Contributing
This gem is managed with Reissue.
Bug reports and pull requests are welcome on GitHub at https://github.com/SOFware/activerecord-null.