Concerns

# Rails Concerns
- http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
- Simplest safest refactoring
  - Just cut and paste the code
- Default part of Rails
- Not just for code shared across models, but super to simply divide change a
  large model file into logical chunks with associated tests.

## Why Concerns and Not Plain Ruby
- Simple to consistently follow the pattern
- Concerns can include other concerns
- Single concern includes all of:
  - instance methods
  - class methods
  - code to run on model including the concern, such as =has_many=, =scope=,
    etc.
- Yes, you can do the same with include, extend, etc., but why risk the
  pitfalls and why not the consistency of Concerns?

## Where to put concerns
- If just one concern for model, or if shared among models, then in
  `app/models/concerns`.
- If multiple concerns for single model, group in subdirectory under models,
  such as `app/models/user/`.


## Steps
- Create file for Concern with skeleton structure:
```ruby
  module ModelName::ConcernName
    extend ActiveSupport::Concern

    included do
      # your class level code
    end

    # move your instance methods here

    module ClassMethods
      # your class methods, removing self.
    end
  end
```
- Move class level code to `included` block.
- Move class methods to inside of module ClassMethods.
- Move instance methods to module.
- Place `include` statement in original model class:
```ruby
  include ModelName::ConcernName
```

## Another Concern Example
- Break out methods concerning a user's feed.
- Now the User is broken up into:
  - user/find_methods.rb
  - user/feed_methods.rb
- Tests similarly matched up.
- I like the smaller files!
- Safe, easy way to slice up huge model files.
- Could be first step to further refactoring.

## Concerns: Didn't Show You But Useful!
- Sharing a concern in multiple models
- Nesting concerns (concerns loading concerns)
- Applies to controllers as well as models

# Concerns Summary
## Applicable Situation
- A giant model file with corresponding giant spec file.
- Duplicated code in multiple models.

## Solution
The giant model can safely and easily be broken down into logical chunks (concerns), each with a
correspondingly smaller spec file per concern.

## Advantages
1. **Ease and safety of refactoring.** Concerns are a great first refactoring step
   because using concerns involves simply moving the methods and tests into
   separate files. And code accessing those methods does not need to change.
2. A core part of Rails 4, so one can expect familiarity among Rails developers.
3. Simplicity. It's just a code organization that makes it easier to navigate to
   the right source and test file.
4. Can DRY up code when a concern is shared among multiple models.

## Disadvantages
1. The model object does not become more cohesive. The code is just better
   organized. In other words, there's no real changes to the API of the model.
2. For a complex operation involving many different methods, and possibly
   multiple models, a Service Object, aka PORO, better groups the logic.
3. If the code view-centric, and relies on helpers, then a Decorator is a better
   choice. 

# Concerns References

-   [Put chubby models on a diet with concerns](http://signalvnoise.com/posts/3372-put-chubby-models-on-a-diet-with-concerns) by @dhh
-   [Reading Rails - Concern](http://monkeyandcrow.com/blog/reading_rails_concern/) by Adam Sanderson
-   [Module ActiveSupport::Concern](http://api.rubyonrails.org/classes/ActiveSupport/Concern.html)