No release in over 3 years
Low commit activity in last 3 years
ConsciousConcern is a decorator for ActiveSupport::Concern that adds several metaprogramming features.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

 Project Readme

ConsciousConcern

Gem Version Build Status Dependency Status Code Climate Test Coverage

ConsciousConcern is a decorator for ActiveSupport::Concern that adds several metaprogramming features, willfully ignoring MVC constraints.

It is useful if you have concerns that are used by a large number of models, or concerns that regulary get added to new models. It consolidates the usage of such concerns by centralizing routing, application of related concerns, migrations, and more.

The examples below are just some possible use cases.

Installation

Add it to your gemfile or run

gem install conscious_concern

Usage

If you are using Rails, add this to your application.rb / engine.rb:

config.to_prepare { ConsciousConcern.load_classes }

This will let ConsciousConcern know about your models and controllers.

Now you can extend ConsciousConcern instead of ActiveSupport::Concern in your modules.

Automatic controller integration

Let's assume you have a Likable concern for your models and a corresponding Liking concern for your controllers. Instead of including Liking manually in your controllers and keeping the controllers up to date when something new becomes Likable or something old is no longer Likable, just add a line to the model concern:

module Likable
  extend ConsciousConcern
  let_controllers(include: Liking)
  # ...
end

Now, if you add Likable to, say, your Comment model, your CommentsController will automatically include Liking. You can also use prepend: or any other methods and arguments.

Shared routes

Draw extra routes for all models that use a concern in one go.

Likable.resources do
  member do
    post 'like'
  end
  collection do
    get 'most_liked'
  end
end

# => like_comment_path(comment)
# => like_event_path(event)
# => like_post_path(post)
# ...
# => most_liked_comments_path
# => most_liked_events_path
# => most_liked_posts_path
# ...

By default, this won't draw the standard RESTful routes, because you've probably done that already.

However, you can pass the usual restriction arguments to draw some or all of them.

Likable.resources(except: [:index]) # block is optional

# => comment_path
# => edit_comment_path
# => new_comment_path
# ...

Shared migrations

Set up database fields for all models that use a concern in one go. This is probably only useful if your data model is pretty much set in stone.

Likable.tables.each do |likable_table|
  change_table likable_table do |t|
    t.integer :like_count, null: false, default: 0
  end
end

Special directory structures, Engines, and no Rails

ConsciousConcern needs to know about your models and controllers. By default, ::load_classes assumes they'll be in the standard Rails paths.

If you have models or controllers in special paths, pass these paths to ::load_classes.

ConsciousConcern.load_classes(my_special_model_dir,
                              my_other_model_dir,
                              my_controller_dir)

If you are using an Engine with the classes in the usual places, just pass it to ::load_classes.

ConsciousConcern.load_classes(engine: MyModule::MyEngine)

If you are using ActiveRecord without Rails, call ::load_classes with rails: false and pass the appropriate directories before using any of the features.

ConsciousConcern.load_classes(my_model_dir, rails: false)

In every case, subdirectories are searched automatically.

Contributions

Feel free to send suggestions, point out issues, or submit pull requests.