Project

kinship

0.0
The project is in a healthy, maintained state
Kinship is a schema-inferred relationship graph for Ruby applications. It automatically discovers parent/child relationships between models by inspecting attributes (e.g. user_id, post_id) and builds a complete in-memory graph with zero configuration. Kinship enables deep relationship traversal, automatic join planning, and eliminates common N+1 query patterns without requiring has_many or belongs_to declarations. It is framework-agnostic and works with Rails, Jetski, and custom ORMs.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

Kinship

Schema‑inferred relationship graphs for Ruby & Rails

Kinship discovers relationships between your models automatically by inspecting columns like user_id, project_id, etc. From that single fact, it builds a full graph of your domain — parents, children, families, paths — without has_many, belongs_to, or configuration.

It exists to solve a very real problem:

Rails knows your schema, but not your graph.

Kinship makes the graph explicit.


Why Kinship exists

Most Rails apps:

  • Define associations manually
  • Forget to preload
  • Accidentally ship N+1 queries
  • Duplicate schema knowledge in code

Example of a very common bad query:

User.all.each do |user|
  user.projects.each do |project|
    project.tasks.each do |task|
      task.comments.each do |comment|
        comment.reactions.each do |reaction|
          reaction.kind
        end
      end
    end
  end
end

Rails allows this. It fails silently. Performance collapses.

Kinship’s philosophy:

If the database already encodes relationships, your application should be able to reason about them automatically.


What Kinship gives you

From nothing more than foreign keys, Kinship builds:

  • parents(model) – one layer up
  • children(model) – one layer down
  • families – connected components
  • path(from, to) – shortest relationship path
  • to_dot – visual graph output

No macros. No DSL. No annotations.


Installation

Ruby / Rails

gem install kinship

or in your Gemfile:

gem "kinship"

Rails usage (recommended setup)

Create an initializer:

# config/initializers/kinship.rb
Rails.application.config.after_initialize do
  Rails.application.eager_load!

  KINSHIP = Kinship.build(
    models: ApplicationRecord.descendants,
    attribute_provider: ->(model) { model.column_names }
  )
end

That’s it.

Kinship now understands your entire domain graph.


Example domain

Given these tables:

  • users
  • projects (user_id)
  • tasks (project_id)
  • comments (task_id)
  • reactions (comment_id)

No associations defined.


Core API

Parents

KINSHIP.parents(Project)
# => { user: User }

Children

KINSHIP.children(Project)
# => { tasks: Task }

Families

KINSHIP.families
# => [[User, Project, Task, Comment, Reaction]]

Path discovery

KINSHIP.path(User, Reaction)
# => [User, Project, Task, Comment, Reaction]

This is the missing abstraction Rails never gave you.


Graph visualization

puts KINSHIP.to_dot

Output:

digraph Kinship {
  "User";
  "Project";
  "Task";
  "Comment";
  "Reaction";
  "User" -> "Project";
  "Project" -> "Task";
  "Task" -> "Comment";
  "Comment" -> "Reaction";
}

You can render this with Graphviz to see your data model.


What Kinship intentionally does not do (yet)

  • Execute SQL
  • Replace ActiveRecord
  • Magically rewrite queries

Instead, it provides the missing layer of understanding required to:

  • detect N+1 queries
  • generate preload plans
  • reason about deep filters
  • visualize data flow

Kinship is the map, avoiding wrong turns.


Framework integrations

Kinship is framework‑agnostic.

It can be embedded into:

  • Rails (today)
  • Jetski (in progress)
  • Custom ORMs
  • Data tooling

Once embedded, all downstream users benefit automatically.


Roadmap (vision)

  • Declarative query intent
  • Automatic preload inference
  • N+1 detection hooks
  • Query planning helpers
  • Console inspection tools

Kinship is designed to cover the 80% of relationship problems that cause 95% of performance bugs.


Philosophy

Databases already encode relationships.

Kinship makes them visible, navigable, and reason‑able.


License

MIT


Built by Kurt Tamulonis