Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Alternative ActiveRecord composition

License

NotificationsYou must be signed in to change notification settings

cedarcode/composition

Repository files navigation

Build StatusCode ClimateGem Version

Alternative composition support forrails applications, for whenActiveRecord'scomposed_of is not enough. This gem adds some behaviorinto composed objects and ways to interact and send messages between boththe one composing and the one being composed.

Installation

Add this line to your application's Gemfile:

gem'composition'

And then execute:

$ bundle

Or install it yourself as:

$ gem install composition

Usage

Composition will enable a new way of defining composed objects into anActiveRecord class. You should have available acompose macro for youruse in your application models.

classUser <ActiveRecord::Basecompose:credit_card,mapping:{credit_card_name::name,credit_card_brand::brand,credit_card_expiration::expiration}end

TheUser class has now available the following methods to manipulatethecredit_card object:

  • User#credit_card
  • User#credit_card=(credit_card)

These methods will operate with a credit_card value object like the onedescribed below:

classCreditCard <Composition::Basecomposed_from:userdefexpired?Date.today >expirationendend

Notice thatCreditCard inherits fromComposition::Base and that thecomposed_from macro is set to:user. This is necessary in order to gainfull access to theuser object from thecredit_card.

How to interact with the value object

With the previous setup in place, now it should be possible to access attributes fromthe database through the value objects instead. You can think of theCreditCardas a normalActiveModel::Model class with the attributes that you alreadyspecified in themapping option.

You would interact with the credit_card object like the following:

user.credit_card_name='Jon Snow'# Set the ActiveRecord attributeuser.credit_card_brand='Visa'# Set the ActiveRecord attributeuser.credit_card_expiration=Date.yesterday# Set the ActiveRecord attributeuser.credit_card# => CreditCard.new(name: 'Jon Snow', brand: 'Visa', expiration: Thu, 11 May 2017)user.credit_card.name# => 'Jon Snow'user.credit_card.brand# => 'Visa'user.credit_card.expiration# => Thu, 11 May 2017user.credit_card.user ==user# => trueuser.credit_card.attributes# => { name: 'Jon Snow', brand: 'Visa', expiration: Thu, 11 May 2017 }user.credit_card.expired?# => true

Modifying the credit_card attributes:

user.credit_card.name# => 'Jon Snow'user.credit_card.name='Arya Stark'# => 'Arya Stark'user.credit_card_name# => 'Arya Stark'user.save# => true

Writing to value objects

The value object can be set by either setting attributes individually, byassigning a new value object, or by usingassign_attributes on the parent.

user.credit_card.name='Jon Snow'user.credit_card.brand='Visa'user.credit_card.expiration=Date.todayuser.credit_card# => CreditCard.new(name: 'Jon Snow', brand: 'Visa', expiration: Thu, 12 May 2017)user.credit_card=CreditCard.new(name:'Jon Snow',brand:'Visa',expiration:Date.today)user.credit_card# => CreditCard.new(name: 'Jon Snow', brand: 'Visa', expiration: Thu, 12 May 2017)user.assign_attributes(credit_card:{name:'Jon Snow',brand:'Visa',expiration:Date.today})user.credit_card# => CreditCard.new(name: 'Jon Snow', brand: 'Visa', expiration: Thu, 12 May 2017)user.update_attributes(credit_card:{name:'Jon Snow',brand:'Visa',expiration:Date.today})user.credit_card# => CreditCard.new(name: 'Jon Snow', brand: 'Visa', expiration: Thu, 12 May 2017)

Validations

If you need to add validations to your value object that should just work.

classCreditCard <Composition::Basecomposed_from:uservalidates:expiration,presence:truedefexpired?Date.today >expirationendenduser.credit_card=CreditCard.new(name:'Jon Snow',brand:'Visa',expiration:nil)user.credit_card.valid?# => false

Detailed macro documentation

Composition will assume some things and use some defaults based on namingconventions for when you definecompose andcomposed_from macros. However,there will be cases where you will have to override the naming convention withsomething custom. Following you will find the complete reference for the providedmacros.

Options for compose

Thecompose method will accept the following options:

:mapping

This is required. It will accept a hash of mappings between the attributesin the parent object and their mapping to the new value object being defined.

classUser <ActiveRecord::Basecompose:credit_card,mapping:{credit_card_name::name,credit_card_brand::brand,credit_card_expiration::expiration}end
:class_name

Optional. If the name of the value object cannot be derived from the compositionname, you can use the:class_name option to supply the class name. If auser hasacredit_card but the name of the class is something likeCCard, then you can use:

classUser <ActiveRecord::Basecompose:credit_card,mapping:{credit_card_name::name,credit_card_brand::brand,credit_card_expiration::expiration},class_name:'CCard'end

Options for composed_from

Thecomposed_from method will accept the following options:

:class_name

Optional. If the name of the value object cannot be derived from the compositionname, you can use the:class_name option to supply the class name. If auser hasacredit_card but the name of the user class is something likeAdminUser, thenyou can use:

classCreditCard <Composition::Basecompose_from:user,class_name:'AdminUser'end

Contributing

  1. Fork it (https://github.com/cedarcode/composition/ )
  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 a new Pull Request

See theRunning Tests guide for details on how to run the test suite.

License

This project is licensed under the MIT License - see theLICENSE file for details

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp