magnet-inc/blue_print

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# BluePrint

[![Gem Version](https://badge.fury.io/rb/blue_print.png)](http://badge.fury.io/rb/blue_print)
[![Build Status](https://travis-ci.org/magnet-inc/blue_print.png?branch=master)](https://travis-ci.org/magnet-inc/blue_print)
[![Coverage Status](https://coveralls.io/repos/magnet-inc/blue_print/badge.png)](https://coveralls.io/r/magnet-inc/blue_print)
[![Code Climate](https://codeclimate.com/github/magnet-inc/blue_print.png)](https://codeclimate.com/github/magnet-inc/blue_print)
[![Dependency Status](https://gemnasium.com/magnet-inc/blue_print.svg)](https://gemnasium.com/magnet-inc/blue_print)

The behavior switching framework. inspired by [DCI](http://en.wikipedia.org/wiki/Data,_context_and_interaction).

## Requirements

- __Ruby__ >= _2.0.0_
  - Tested ruby version:
    - 2.0.0
    - 2.1.0
    - 2.1.1
    - head

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'blue_print', '~> 1.3.0'
```

## Usage

### Integration

BluePrint provides some integrations. Now supported libraries:

- [Ruby on Rails](http://rubyonrails.org/) >= 3.1
- [Grape](http://intridea.github.io/grape/)
- [Draper](https://github.com/drapergem/draper)
- [RSpec](https://github.com/rspec)

### Rails Generators

BluePrint provides a generator to create templates of a context and behaviros.

```bash
$ rails generate blue_print staff user:staff_user
     create  app/blue_prints/staff_context.rb
     create  app/blue_prints/staff_context/staff_user.rb
     invoke  rspec
     create    spec/blue_prints/staff_context_spec.rb
     create    spec/blue_prints/staff_context/staff_user_spec.rb
```

### Contexts

Contexts inherit from `BluePrint::Context`, live in your `app/blue_prints` directory.

#### active_if

This block is used to decide if this context active or not. `env` is the `BluePrint.env`. `self` is passed via `BluePrint::Environment#context`. By default, this is set as `active_if { false }`.

```ruby
class StaffContext < BluePrint::Context
  active_if do |env|
    current_user.try(:staff?)
  end
end
```

And you can define named active if:

```ruby
# lib/active_ifs/staff.rb
BluePrint::ActiveIf.new(:staff) do |env|
  current_user.try(:staff?)
end

# app/blue_prints/staff_context.rb
class StaffContext < BluePrint::Context
  active_if :staff
end
```

#### Casting

Contexts has casting. This is used to decide classes cast as behaviors if this context active.

```ruby
class StaffContext < BluePrint::Context
  cast ::User, as: [StaffUser]
end

StaffContext.casting
# =>
#   {
#     User => [ StaffUser ]
#   }
```

### Behaviors

Behaviors extended by `BluePrint::Behavior`, live in your `app/blue_prints/{context}` directory.

```ruby
# app/blue_prints/staff_context/staff_user.rb
module StaffContext::StaffUser
  extend BluePrint::Behavior
end
```

#### Methods

Behaviors can have some methods.

```ruby
# app/blue_prints/staff_context/staff_user.rb
module StaffContext::StaffUser
  extend BluePrint::Behavior

  def user_name
    "staff"
  end
end

# app/models/user.rb
class User < ActiveRecord::Base
  def user_name
    "#{name} san"
  end
end

user = User.new(name: "Magnet")
StaffContext.deactivate!
user.user_name # => "Magnet san"
StaffContext.activate!
user.user_name # => "staff"
```

#### Class Methods

Behaviors can have some class methods.

```ruby
# app/blue_prints/staff_context/staff_user.rb
module StaffContext::StaffUser
  extend BluePrint::Behavior

  module ClassMethods
    def find(id)
      where(id: id, staff: true).first!
    end
  end
end

# app/models/user.rb
class User < ActiveRecord::Base
end

user = User.create(staff: false)
StaffContext.deactivate!
User.find(user.id) == user # => true
StaffContext.activate!
User.find(user.id) # => raise ActiveRecord::NotFound
```

### Helper

`BluePrint::Helper` provides `#within_context_of` and `#without_context_of`.

This module includes automatically to some classes. see [lib/blue_print/integration](https://github.com/magnet-inc/blue_print/tree/master/lib/blue_print/integration).

## Contributing

1. Fork it ( http://github.com/magnet-inc/blue_print/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request