SimpleExposure
Simplify sharing state between Rails controllers and views and reduce noise in Rails controllers for those who are tired of writing the same code over and over again.
Based on the idea behind view_accessor borrowing features I like from decent_exposure.
Basic example
# controllers/projects_controller.rb
class ProjectsController < ApplicationController
  expose(:projects) { Project.all }
end
# views/projects/index.html.slim
- projects.each do |project|
  p = project.titleWait, there's more!
Installation
Add this line to your application's Gemfile:
gem 'simple_exposure'
And then execute:
$ bundle
Or install it yourself as:
$ gem install simple_exposure
Usage
Share controller's state to the views:
# controllers/projects_controller.rb
class ProjectsController < ApplicationController
  expose :projects, :project
  def index
    self.projects = Project.all
  end
  def show
    self.project = Project.find(1)
  end
end
# views/projects/index.html.slim
- projects.each do |project|
  p = project.titleExpose controller methods to the views:
# controllers/projects_controller.rb
class ProjectsController < ApplicationController
  expose :project
  private
  def project
    @project ||= Project.find(1)
  end
endProvide default values
class ProjectsController < ApplicationController
  expose(:projects) { Project.all }
endRemove common noise with extensions
Before:
class ProjectsController < ApplicationController
  def index
    @projects = Project.page(params[:page])
  end
endAfter:
class ProjectsController < ApplicationController
  paginate :projects
  def index
    self.projects = Project.all
  end
endWhich is the same as:
class ProjectsController < ApplicationController
  expose :projects, extend: :paginate
  def index
    self.projects = Project.all
  end
endCombine multiple extensions
Before:
class ProjectsController < ApplicationController
  def index
    @projects = Project.page(params[:page]).decorate
  end
endAfter:
class ProjectsController < ApplicationController
  paginate :projects, extend: :decorate
  def index
    self.projects = Project.all
  end
endWhich is the same as:
class ProjectsController < ApplicationController
  expose :projects, extend: %i(paginate decorate)
  def index
    self.projects = Project.all
  end
endCombine it all together for a greater good
Before:
class ProjectsController < ApplicationController
  def index
    @projects = current_user.projects.ordered
    @completed_projects = @projects.completed.page(params[:page])
    @current_user = current_user.decorate
  end
endAfter:
class ProjectsController < ApplicationController
  decorate :current_user
  expose :projects do
    current_user.projects.ordered
  end
  paginate(:completed_projects) { projects.completed }
endExtensions
Built-in extensions
Library provides two built-in extensions:
- paginate (Kaminari)
- decorate (Draper)
Writing your own extensions
module SimpleExposure
  module Extensions
    module MyExtension
      extend self
      def apply(value, controller)
        # Do something with the value here
      end
    end
  end
end
class ProjectsController < ApplicationController
  my_extension :projects
  # or
  expose :projects, extend: :my_extension
endNote that extensions are applied at the time of render, not immediately when the value is assigned.
Similar projects
Contributing
- Fork it
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create new Pull Request