presenter on rails

https://github.com/angelfan/DayDayUp/blob/master/note/presenter.md

presenter on rails

ruby on rails 属于 MVC 框架, 对于简单的应用三层可能就够用了, 可是当应用愈来愈复杂可能就须要更多的抽象层来知足业务需求, 好比service, presenter 好比有些人认为应用逻辑(业务逻辑)不该该放在数据层(Model),或者一个 Model 只应该管好他本身的事情,多个 Model 的融合须要另外的类来作代理。git

Model != View

不少状况下, view中会有这样的相似写法 @article.published? && @article.user_type == 'Admin' 也许能够把他放到model中定义出一个方法, 好比github

class Artice < ActiveRecord::Base def published_by_admin? published? && user_type == 'Admin  end end

或者你也能够把他放到 helper中去 而后view中就能够这样用@article.published_by_admin 可是随着逻辑愈来愈多, model中相似的方法也会愈来愈多, 可是model中应该主要用来放业务逻辑 因此须要额外抽象出presenter层来处理ruby

Demo

## 代码连接 https://github.com/railscasts/287-presenters-from-scratch
class BasePresenter def initialize(object, template) @object = object @template = template end def object @object end private def self.presents(name) define_method(name) do @object end end def h @template end # this allows any template methods to be called directly from presenter code. def method_missing(*args, &block) # TODO check for @template.respond_to? and return raw values if nil @template.send(*args, &block) end end class UserPresenter < BasePresenter presents :user delegate :username, to: :user def full_name "#{first_name}-#{last_name}" end end # helper 中增长该方法 module ApplicationHelper def present(object, klass = nil) klass ||= "#{object.class}Presenter".constantize presenter = klass.new(object, self) yield presenter if block_given? presenter end end # in view <% present @user do |user_presenter| %>  <p><%= user_presenter.fullname %></p> <% end %>

这样无论是model 仍是 helper都会变得很干净, 最重要的是 变得更容易测试框架

推荐的gem Draper测试

相关文章
相关标签/搜索