-
Notifications
You must be signed in to change notification settings - Fork 5
One Big Fat Example
floere edited this page Sep 13, 2010
·
8 revisions
Think Amazon. It is about a bookstore that shows prices in the user’s currency. Also, it carries books AND toys as items in several views where items are listed. (And toys and books are rendered differently, but have to be able to be in the same list of recommendations for example)
The following classes all have specs of course ;) But are not shown since they don’t help the example.
ViewModels superclass for this project.
We include all of Rails’ helpers for the view models in this project.
Also, we include the ApplicationHelper.
We delegate logger and current_user calls in the view models to the active controller.
class ViewModels::Project < ViewModels::Base
# Our ApplicationHelper.
#
helper ApplicationHelper
# We want to be able to call view_model_for in our view_models.
#
helper ViewModels::Helpers::Rails
# Include all common view helpers.
#
helper ViewModels::Helpers::View
# We want to be able to use id, dom_id, to_param on the view model.
#
# Note: Overrides the standard dom_id method from the RecordIdentificationHelper.
#
include ViewModels::Extensions::ActiveRecord
# This delegates any calls to logger and current_user in the view models to the controller.
#
controller_method :logger, :current_user
end
# All items have a description that needs to be filtered by textilize.
#
class ViewModels::Item < ViewModels::Project
model_reader :description, :filter_through => :textilize
# Use price in the view as follows:
# = view_model.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/view_models/book
# that are called
# _cart_item.html.haml
# _cart_item.text.erb
#
# Call view_model_for on a book in the view or controller to get this view_model.
#
class ViewModels::Book < ViewModels::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/view_models/toy
# that are called
# _cart_item.html.haml
# _cart_item.text.erb
#
# Call view_model_for on a toy in the view or controller to get this view_model.
#
class ViewModels::Toy < ViewModels::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