Contextualize
Adds the ability to add and remove specific modules to an object depending on the current context
This can fx be used for Models in a MVC pattern, where the model could have different behavior
depending on the context it operates in, fx if is currently accessed in a View or a Controller, or
even depending on the scope (fx Admin) etc.
This way, a lot of the typical scenarios for helper methods can be avoided. Instead you simply create
an ‘app/contexts’ folder for modules that define contextual behavior for the models. You can further
subdivision these contexts as needed. This can even be used to redefine the logic of a method depending
on the context it operates in.
The Decorator Pattern with Mixology has been used to great effect.
Basic Usage
Define each context specific module
module ProjectView # display the best project def show_best # calls method :best end end module ProjectControl # select the best project def best end end module Admin module ProjectControl # admin specific logic to select the best project! def best end end end # Only in order to faciliatet demonstrating results below! class Object def own_methods methods - Object.methods end end
Then bind these modules to one or more contexts
class Project contextualize contexts :view, :control # using naming conventions context :admin, Admin::ProjectControl end
Now you can operate on the object according to the context you are in
project = Project.new # add :view context project.add_context :view project.add_contexts :view, :control # use the view context methods now available project.own_methods.should include('view') project.view.should == "view" # remove the :view context project.remove_context :view project.remove_contexts :view, :control # the methods of the view context are no longer available! lambda {project.view}.should raise_error # operate on object within one or more contexts project.context_scope :view do |project| project.view.should == "view" end # contexts are automatically removed from object when block terminates lambda {project.view}.should raise_error project.context_scope :view, :control do |project| # ... end
Usage in Rails
in Gemfile
gem 'contextualize'
In a Rails project, you should use the following file structure
+ app + contexts project_view.rb project_control.rb + admin project_view.rb + models project.rb
class ProjectsController < ApplicationController # "simulated" exposure def project @project ||= begin p = params[:id] ? Project.find(params[:id]) : Project.new(params[:project]) p.add_icontext :view end end helper_method project hide_action project def projects @projects ||= Project.all.add_icontext :view end helper_method projects hide_action projects def index end def show end ... end
Using decent_exposure integration
Contextualize monkey-patches the #expose method of the decent_exposure gem to add the icontext :view to each model (if present)
in Gemfile
gem 'decent_exposure' gem 'contextualize'
class ProjectsController < ApplicationController expose(:projects) { Project.all } expose(:project) def index end def show end def new end def edit end def create if project.save redirect_to project, notice: 'Project was successfully created.' else render action: "new" end end def update if project.update_attributes(params[:project]) redirect_to project, notice: 'Project was successfully updated.' else render action: "edit" end end def destroy project.destroy redirect_to projects_url end end
Enjoy!
Contributing to contextualize
- Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
- Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
- Fork the project
- Start a feature/bugfix branch
- Commit and push until you are happy with your contribution
- Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright © 2011 Kristian Mandrup. See LICENSE.txt for
further details.