Ownership
Code ownership for Rails
Check out Scaling the Monolith for other tips
🍊 Battle-tested at Instacart
Installation
Add this line to your application’s Gemfile:
gem "ownership"Getting Started
Ownership provides the ability to specify owners for different parts of the codebase. We highly recommend owners are teams rather than individuals. You can then use this information however you’d like, like routing errors to the correct team.
Specifying Ownership
Controllers
class OrdersController < ApplicationController
owner :logistics
endYou can use any options that before_action supports.
class OrdersController < ApplicationController
owner :logistics, only: [:index]
owner :customers, except: [:index]
endJobs
class SomeJob < ApplicationJob
owner :logistics
endAnywhere
owner :logistics do
# code
endDefault
You can set a default owner with:
Ownership.default_owner = :logisticsIntegrations
There are a few built-in integrations with other gems.
- Active Record
- AppSignal
- Honeybadger
- Rollbar
You can also add custom integrations.
Active Record
Active Record has the option to add comments to queries.
SELECT ...
/*application:MyApp,controller:posts,action:index,owner:logistics*/Add to config/application.rb:
config.active_record.query_log_tags_enabled = true
config.active_record.query_log_tags << :ownerAppSignal
The AppSignal gem integrates with Ownership automatically. Error and performance samples in AppSignal will be tagged with the specified owner.
You can set AppSignal's ownership_set_namespace configuration option to true in order to use the specified owner as an AppSignal namespace, which allows you to easily list performance actions and error incidents for each namespace.
Honeybadger
Honeybadger tracks exceptions. This integration makes it easy to send exceptions to different projects based on the owner. We recommend having a project for each team.
Ownership::Honeybadger.api_keys = {
logistics: "token1",
customers: "token2"
}Also works with a proc
Ownership::Honeybadger.api_keys = ->(owner) { ENV["#{owner.to_s.upcase}_HONEYBADGER_API_KEY"] }Rollbar
Rollbar tracks exceptions. This integration makes it easy to send exceptions to different projects based on the owner. We recommend having a project for each team.
Ownership::Rollbar.access_token = {
logistics: "token1",
customers: "token2"
}Also works with a proc
Ownership::Rollbar.access_token = ->(owner) { ENV["#{owner.to_s.upcase}_ROLLBAR_ACCESS_TOKEN"] }For version 3.1+ of the rollbar gem, add to config/initializers/rollbar.rb:
config.use_payload_access_token = trueCustom Integrations
You can define a custom block of code to run with:
Ownership.around_change = proc do |owner, block|
puts "New owner: #{owner}"
block.call
puts "Done"
endExceptions that bubble up from an owner block have the owner, which your exception reporting library can use.
begin
owner :logistics do
raise "error"
end
rescue => e
puts e.owner # :logistics
endOther Useful Tools
- GitHub Code Owners for code reviews
Thanks
Thanks to Nick Elser for creating this pattern.
History
View the changelog
Contributing
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development and testing:
git clone https://github.com/ankane/ownership.git
cd ownership
bundle install
bundle exec rake test