Class: SimplePresenter::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/simple_presenter/base.rb,
lib/simple_presenter/rails.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*subjects) ⇒ Base

It assigns the subjects.

user = UserPresenter.new(User.first)

You can assign several subjects if you want.

 class CommentPresenter < Presenter
   subject :comment, :post
   expose :body
   expose :title, :with => :post
 end

comment = CommentPresenter.new(Comment.first, Post.first)

If the :with option specified to one of the subjects, then the default subject is bypassed. Otherwise, it will be proxied to the default subject.



131
132
133
134
135
# File 'lib/simple_presenter/base.rb', line 131

def initialize(*subjects)
  self.class.subjects.each_with_index do |name, index|
    instance_variable_set("@#{name}", subjects[index])
  end
end

Class Method Details

.attributesObject

Store all attributes and options that have been exposed.

class UserPresenter < Presenter
  expose :name
  expose :street, with: "address"
end

UserPresenter.attributes
#=> {
#=>   name: [:name, {}],
#=>   address_street: [:street, {with: "address"}]
#=> }


58
59
60
# File 'lib/simple_presenter/base.rb', line 58

def self.attributes
  @attributes ||= {}
end

.expose(*attrs) ⇒ Object

The list of attributes that will be exposed.

class UserPresenter < Presenter
  expose :name, :email
end

You can also expose an attribute from a composition.

class CommentPresenter < Presenter
  expose :body, :created_at
  expose :name, :with => :user
  expose :name, :as => :author
end

The presenter above will expose the methods body, created_at, and user_name. Additionaly, it will create an alias called author to the name attribute.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/simple_presenter/base.rb', line 92

def self.expose(*attrs)
  options = attrs.pop if attrs.last.kind_of?(Hash)
  options ||= {}

  attrs.each do |attr_name|
    subject = options.fetch(:with, nil)

    method_name = [
      subject,
      options.fetch(:as, attr_name)
    ].compact.join("_")

    attributes[method_name.to_sym] = [attr_name, options]

    class_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{method_name}(&block)                                    # def user_name(&block)
        proxy_message(#{subject.inspect}, "#{attr_name}", &block)   #   proxy_message("user", "name")
      end                                                           # end
    RUBY
  end
end

.inherited(child) ⇒ Object

Propagate inherited subjects and attributes.



38
39
40
41
42
43
# File 'lib/simple_presenter/base.rb', line 38

def self.inherited(child)
  child.subjects(*subjects)
  attributes.each_value do |attr_name, options|
    child.expose(attr_name, options)
  end
end

.map(collection, *subjects) ⇒ Object

This method will return a presenter for each item of collection.

users = UserPresenter.map(User.all)

If your presenter accepts more than one subject, you can provided them as following parameters.

comments = CommentPresenter.map(post.comment.all, post)


71
72
73
# File 'lib/simple_presenter/base.rb', line 71

def self.map(collection, *subjects)
  collection.map {|item| new(item, *subjects)}
end

.routesObject



16
17
18
# File 'lib/simple_presenter/rails.rb', line 16

def self.routes
  @routes ||= Object.new.extend(routes_module)
end

.routes_moduleObject



9
10
11
12
13
14
# File 'lib/simple_presenter/rails.rb', line 9

def self.routes_module
  @routes_module ||= Module.new do
    include Rails.application.routes.url_helpers
    include UrlMethods
  end
end

.subjects(*names) ⇒ Object Also known as: subject

Define how many subjects this presenter will receive. Each subject will create a private method with the same name.

The first subject name will be used as default, thus isn’t required as :with option on the SimplePresenter::Base.expose method.

class CommentPresenter < Presenter
  subjects :comment, :post
  expose :body                  # will expose comment.body through CommentPresenter#body
  expose :title, :with => :post # will expose post.title through CommentPresenter#post_title
end

Subjects can be accessed by a private name with the same name. So the above subjects can be accessed internally by the methods comment and post.

If you’re not setting any special name, then you can access it using the subject method.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/simple_presenter/base.rb', line 20

def self.subjects(*names)
  @subjects ||= [:subject]

  unless names.empty?
    @subjects = names
    attr_reader *names
    private *names
  end

  @subjects
end

Instance Method Details

#helpersObject Also known as: h



25
26
27
# File 'lib/simple_presenter/rails.rb', line 25

def helpers
  ApplicationController.helpers
end

#routesObject Also known as: r



20
21
22
# File 'lib/simple_presenter/rails.rb', line 20

def routes
  self.class.routes
end