Skip to content

A gem for creating self-referential parent child relationships on a model

License

Notifications You must be signed in to change notification settings

brookisme/familyable

Repository files navigation

Familyable

This gem makes creating self-referential parent child relationships on a model easy. So for a Person model you have person.parent and person.children where the parent and children are also people.

You also get the following instance methods:

  • descendents
  • elders
  • siblings
  • family
  • master - the 'oldest' in the family

and the class method:

  • masters - everyone without a parent

Standard stuff I know but...

Everyone of the methods above works with a single call to the data base!!!

This is a huge performance gain. In fact, being able build the above methods with a single database call was the entire motivation for gemifiying something that otherwise was entirely straight forward. It should be noted that this was built the day after reading this.


WARNING: This project is still in development
[x] create relationship concern
[X] create generators for relationship models
[X] check that it works with engines
[ ] add generation handling
[ ] generate data for testapp
[ ] tests tests tests
[ ] refactor concern
[ ] add servents methods (class and instance)?

Requirments

You must be using a postgres data base... thats where the single-db-query magic happens.

Installation

Note: use with caution. This gem is still in developement

Gemfile

gem 'familyable'
$  bundle install

Usage


Example: Adding Relationships to an existing Person model:

Step 1: Generate Relationship Model
$  bundle exec rails g familyable:relationships Person
$  bundle exec rake db:migrate
Step 2: Add Relationships Concern to Model

app/models/person.rb

class Person < ActiveRecord::Base
    include Familyable::Relationships
    ...
end

For use inside of rails engines see this note.

Step 3: Add Generation Handling

Until we create a generator for this step you need to add a call back to the relationships model to handle setting person.generation

app/models/person_relationship.rb

#
# generation handling 
#
    before_save :update_generation

private

    def update_generation
      child.set_generation
      child.save
    end
Step 4: You're done! start coding

quick note: all the instance methods above (accept for master) take an optional parameter include_self=false. it does what you exactly what you think.

Person.masters
person.master
person.descendents
person.descendents(true)
...

Rails Engine Note: For use with rails engines use the full model name from the the root of your Engine directory and require it in your engine.rb

$  bundle exec rails g familyable:relationships EngineName::Person

lib/engine_name/engine.rb

...
require 'familyable'
module EngineName
  class Engine < ::Rails::Engine
  ...

About

A gem for creating self-referential parent child relationships on a model

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages