Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/floere/representer

DEPRECATED: PLEASE SEE THE view_models LINK BELOW.
https://github.com/floere/representer

Last synced: 2 months ago
JSON representation

DEPRECATED: PLEASE SEE THE view_models LINK BELOW.

Awesome Lists containing this project

README

        

# Representers for Rails
# A possible representer solution, i.e. no view logic in model code.
# Ask/Write [email protected] if you have questions/feedback, thanks! :)
# Fork if you have improvements. Tell me where to merge them from, thanks!
#
# Problem: Display Methods are not well placed either in
# * models: Violation of the MVC principle.
# * helpers: No Polymorphism.
# Solution:
# A thin proxy layer over a model, with access to the controller, used by the view or controller.
#
# IMPORTANT NOTE:
# As of yet it is needed to copy the representer/views/representers/collection
# directory to the corresponding location in app/views/representers/collection.
# This is only needed if you wish to use the collection rpresenter.
# Note: Rewrite the collection templates as needed, they are rather basic.
#
# * Getting a representer in a view or a controller.
#
# Call representer_for:
# Note: By convention, uses Representers::Model::Class::Name, thus prefixing Representers:: to
# the model class name.
presenter_instance = representer_for model_instance

# * Getting a collection representer in a view.
#
# The collection representer renders each of the given items with its representer.
#
# Call collection_presenter_for:
collection_presenter_instance = collection_presenter_for enumerable_containing_model_instances
# Rendering a list.
collection_presenter_instance.list
# Rendering a collection.
collection_presenter_instance.collection
# Rendering a table.
collection_presenter_instance.table
# Rendering a pagination.
# Note: Only works if the passed parameter for collection_presenter_for is a PaginationEnumeration.
collection_presenter_instance.pagination

# * Writing filtered delegate methods on the representer.
#
# Will create two delegate methods first_name and last_name that delegate to the model.
model_reader :first_name, :last_name
# Will create a description delegate method that filters the model value through h.
model_reader :description, :filter_through => :h
# Will create a description delegate method that filters the model value through first textilize, then h.
model_reader :description, :filter_through => [:textilize, :h]
# Will create both a first_name and last_name delegate method
# that filters the model value through first textilize, then h.
model_reader :first_name, :last_name, :filter_through => [:textilize, :h]
# Note: Filter methods can be any method on the representer with arity 1.

# * Rendering representer templates
#
# Use render_as(template_name, format = nil).
#
# Gets a Representers::Model::Class instance
presenter = representer_for Model::Class.new
# Gets a Representers:: instance
presenter = representer_for model_instance
# Renders the 'example' partial in representers/model/class.
# Note: Renders a format depending on the request. ../index.text will render example.text.erb.
presenter.render_as :example
# Renders the 'example.text.erb' partial in representers/model/class.
presenter.render_as :example, :text

# * Rails Helpers in Representers
#
# Use helper as in the controller.
helper ActionView::Helpers::UrlHelper
helper ApplicationHelper
# Note: It is helpful to create a superclass to all representers in the project
# with generally used helpers.
# We use Representers::Project a lot, for example. See example below.

# * Controller Delegate Methods
#
# Use controller_method(*args).
#
# Delegates current_user and logger on the representer to the controller.
controller_method :current_user, :logger

# * Big Example
#
# The following classes all have specs of course ;) But are not shown since they don't help the example.

# Representers superclass for this project.
#
# We include all of Rails' helpers for the representers in this project.
# Also, we include the ApplicationHelper.
#
# We delegate logger and current_user calls in the representers to
# the active controller.
#
class Representers::Project < Representers::Base

# All of Rails' standard helpers.
helper ActionView::Helpers::ActiveRecordHelper
helper ActionView::Helpers::TagHelper
helper ActionView::Helpers::FormTagHelper
helper ActionView::Helpers::FormOptionsHelper
helper ActionView::Helpers::FormHelper
helper ActionView::Helpers::UrlHelper
helper ActionView::Helpers::AssetTagHelper
helper ActionView::Helpers::PrototypeHelper
helper ActionView::Helpers::TextHelper

helper ApplicationHelper

controller_method :logger, :current_user

end

# All items have a description that needs to be filtered by textilize.
#
class Representers::Item < Representers::Project
model_reader :description, :filter_through => :textilize
# Use price in the view as follows:
# = representer.price - will display e.g. 16.57 CHF, since it is filtered first through localize_currency
model_reader :price, :filter_through => :localize_currency

# Converts a database price tag to the users chosen value, with the users preferred currency appended.
# If the user is Swiss, localize_currency will convert 10 Euros to "16.57 CHF"
#
def localize_currency(price_in_euros)
converted_price = current_user.convert_price(price_in_euros)
"#{converted_price} #{current_user.currency.to_s}"
end
end

# This class also has partial templates in the directory
# app/views/representers/book
# that are called
# _cart_item.html.haml
# _cart_item.text.erb
#
# Call representer_for on a book in the view or controller to get this representer.
#
class Representers::Book < Representers::Item
model_reader :author, :title, :pages
model_reader :excerpt, :filter_through => :textilize

def header
content_tag(:h1, "#{author} – #{title}")
end

def full_description
content_tag(:p, "#{excerpt} #{description}", :class => 'description full')
end
end

# This class also has partial templates in the directory
# app/views/representers/toy
# that are called
# _cart_item.html.haml
# _cart_item.text.erb
#
# Call representer_for on a toy in the view or controller to get this representer.
#
class Representers::Toy < Representers::Item
model_reader :starting_age, :small_dangerous_parts

def obligatory_parental_warning
"Warning, this toy can only be used by kids ages #{starting_age} and up. Your department of health. Thank you."
end

end