djonasson/symmetry

View on GitHub
README.rdoc

Summary

Maintainability
Test Coverage
= Symmetry

{<img src="https://travis-ci.org/djonasson/symmetry.png?branch=master" alt="Build Status" />}[https://travis-ci.org/djonasson/symmetry]
{<img src="https://gemnasium.com/djonasson/symmetry.png" alt="Dependency Status" />}[https://gemnasium.com/djonasson/symmetry]
{<img src="https://codeclimate.com/github/djonasson/symmetry.png" alt="Code Climate" />}[https://codeclimate.com/github/djonasson/symmetry]
{<img src="https://coveralls.io/repos/djonasson/symmetry/badge.png?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/djonasson/symmetry]
{<img src="https://badge.fury.io/rb/symmetry.png" alt="Gem Version" />}[http://badge.fury.io/rb/symmetry]

Symmetry gives you a simple way of creating symmetric has_and_belongs_to_many relationships (friends, neighbors, etc.) in your Active Record models.


== Installation

Add it to your Gemfile:

  gem "symmetry"

Install the migrations:

  rails symmetry_engine:install:migrations db:migrate


== Usage

Define a symmetric relationship:

  class User < ApplicationRecord
    symmetric_relationship :friends
  end

  class Country < ApplicationRecord
    symmetric_relationship :neighbors, polymorphic_relationship_name: :neighborships
  end

Use it:

  # User

  irb(main)> u = User.create(name: "Daniel")
  => #<User id: 1, name: "Daniel", ...>

  irb(main)> u.friends
  => []

  irb(main)> u.friend_relationships
  => []


  # Country

  irb(main)> c = Country.create(name: "Sweden")
  => #<Country id: 1, name: "Sweden", ...>

  irb(main)> c.neighbors << Country.create(name: "Norway")
  => [#<Country id: 2, name: "Norway", ...>]

  irb(main)> c.neighbors
  => [#<Country id: 2, name: "Norway", ...>]

  irb(main)> Country.find(2).neighbors
  => [#<Country id: 1, name: "Sweden", ...>]

  irb(main)> c.neighborships
  => [#<SymmetricRelationship id: 1, owner_id: 1, owner_type: "Country", relation_id: 2, relation_type: "Country", relationship_name: "neighbors" ...>, ...]

It is possible to define multiple symmetric relationships on the same model:

  class Politician < ApplicationRecord
    symmetric_relationship :friends
    symmetric_relationship :enemies
  end

  irb(main)> p1 = Politician.create(name: 'A')
  => #<Politician id: 1, name: "A", ...>

  irb(main)> p2 = Politician.create(name: 'B')
  => #<Politician id: 2, name: "B", ...>

  irb(main)> p3 = Politician.create(name: 'C')
  => #<Politician id: 3, name: "C", ...>

  irb(main)> p1.friends
  => []

  irb(main)> p1.enemies
  => []

  irb(main)> p1.friends << p2
  => [#<Politician id: 2, name: "B", ...>]

  irb(main)> p1.enemies << p3
  => [#<Politician id: 3, name: "C", ...>]

  irb(main)> p1.friends.count
  => 1

  irb(main)> p1.enemies.count
  => 1

  irb(main)> p2.friends.count
  => 1

  irb(main)> p2.enemies.count
  => 0