项目作者: RichOrElse

项目描述 :
Wrapper Based DCI implementation in Ruby.
高级语言: Ruby
项目地址: git://github.com/RichOrElse/wrapper-based.git
创建时间: 2017-06-16T14:25:54Z
项目社区:https://github.com/RichOrElse/wrapper-based

开源协议:MIT License

下载


WrapperBased

Gem Version
Build Status

Wrapper Based DCI framework for OOP done right.

Installation

Add this line to your application’s Gemfile:

  1. gem 'wrapper_based'

And then execute:

  1. $ bundle

DCI::Roles

Includes role components into classes. For each role it defines private accessor methods.

Usage

It accepts Classes that can be initialized with an argument, like so:

  1. class SignsUser < Struct.new(:signed)
  2. def in!(user)
  3. signed[:user_id] = user.id
  4. end
  5. def out!
  6. signed.delete(:user_id)
  7. @user = nil
  8. end
  9. def out?
  10. signed[:user_id].nil? || in?
  11. end
  12. def in?
  13. !user.nil?
  14. end
  15. def user
  16. @user ||= by(id: signed[:user_id])
  17. end
  18. def by(**identification)
  19. User.find_by identification
  20. end
  21. def with(**credentials)
  22. User.new credentials
  23. end
  24. def up!(user)
  25. user.save && user if User.validate_registering(user)
  26. end
  27. end

Assign values using role binding methods prefixed by ‘with_’ and ended by an exclamation mark ‘!’.

  1. class ApplicationController
  2. include DCI::Roles(:current_user, logged: SignsUser)
  3. before_action -> { with_logged! session }
  4. helper_method :current_user, :logged
  5. private
  6. def authenticate_user!
  7. if logged.out?
  8. flash[:error] = "You must be logged in to access this section"
  9. redirect_to login_url
  10. else
  11. with_current_user! logged.user
  12. end
  13. end
  14. end
  15. class LogoutController < ApplicationController
  16. include DCI::Roles(signing: SignsUser)
  17. before_action -> { with_signing! session }
  18. def destroy
  19. signing.out!
  20. redirect_to root_url
  21. end
  22. end

It also accept Modules but no procedural code allowed, meaning only call the role player object methods and avoid calling the other methods defined in the Module.

  1. module UserParams
  2. def registration
  3. permit(:username, :email)
  4. end
  5. def login
  6. permit(:username, :email)
  7. end
  8. def security
  9. permit(:password, :password_confirmation, :code)
  10. end
  11. def password
  12. fetch(:password, '')
  13. end
  14. end

Mass assign values to multiple components using ‘with!’ method.

  1. class LoginController < ApplicationController
  2. include DCI::Roles(signing: SignsUser, user_params: UserParams, login: HasEncryptedPassword)
  3. before_action -> { with! signing: session, user_params: params.require(:user) }
  4. before_action -> { with! login: signing.by(user_params.login) }
  5. def new; end
  6. def create
  7. if login.authenticate(user_params.password)
  8. signing.in! login
  9. redirect_to login, notice: 'Welcome, you are now logged in.'
  10. else
  11. flash[:danger] = 'Invalid credentials.'
  12. render :new, status: :unauthorized
  13. end
  14. end
  15. end

A role’s instance variable holds plain value (without the new behavior).

DCI::Context

Usage

  1. class GiftToy < DCI::Context(:toy, gifter: Buyer, giftee: Recipient)
  2. def call(toy = @toy)
  3. gift = gifter.buy
  4. giftee.receive gift
  5. end
  6. end

Context#to_proc

Returns call method as a Proc.

  1. ['Card Wars', 'Ice Ninja Manual', 'Bacon'].map &GiftToy[gifter: 'Jake', giftee: 'Finn']

Context::call

A shortcut for instantiating the context by passing the collaborators and then executing the context call method.

  1. Funds::TransferMoney.(from: @account1, to: @account2, amount: 50)

Which is equivalent to:

  1. Funds::TransferMoney.new(from: @account1, to: @account2, amount: 50).call

Context Examples

Money Transfer |
Djikstra |
Toy Shop |
Acapella |
Background Job |
Facade |
HTTP API Client |
all examples

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/RichOrElse/wrapper-based.

License

The gem is available as open source under the terms of the MIT License.