Fine for simple stuff
If we try to follow the
Single Responsibility Principle
“ every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility ”
MVC may not be enough
As a visitor to the site
I can see a list of all users and their ages
Sorted by name
So I can easily find out demographics of users in our system
# users_controller.rb
def index
@users = User.all
end
/ users/show.slim
h2 Users
table
- @users.select{|u| u.active}.sort_by{|u| [u.first_name, u.last_name].map(&:downcase)}.each do |user|
tr
td.name = "#{user.first_name} #{user.last_name}"
td.age = "#{Time.zone.now.year - user.birthdate.year}"
Display logic is contained in the view
# user.rb
class User
scope :by_name, -> { order('first_name, last_name') }
scope :active, -> { where(:active => true) }
end
# users_controller.rb
def index
@users = User.active.by_name
end
/ users/show.slim
h2 Users
table
- @users.each do |user|
tr
td.name = "#{user.first_name} #{user.last_name}"
td.age = "#{Time.zone.now.year - user.birthdate.year}"
Less display logic in the view
# user.rb
class User
scope :by_name, -> { order('first_name, last_name') }
scope :active, -> { where(:active => true) }
end
# users_controller.rb
def index
@users = UsersPresenter.new
end
/ users/show.slim
h2 Users
table
- @users.each do |user|
tr
td.name = user.name
td.age = user.age
# users_presenter.rb
class UsersPresenter
def users
@users ||= User.active.by_name.map{|u| UserPresenter.new(u)}
end
end
# user_presenter.rb
class UserPresenter
attr_reader :user
def initialize(user)
@user = user
end
def name
@name ||= [user.first_name, user.last_name].join(" ")
end
def age
@age ||= (Time.zone.now.year - user.birthdate.year)
end
end
Display Logic is in the presenter
try it... I bet you'll find more uses
Mr Rogers jon@carbonfive.com bunnymatic @rcode5