Ruby on Rails - Railscasts PRO #287 Presenters from Scratch (pro)

By: Railscasts Reloaded

61   2   13303

Uploaded on 10/24/2014

Clean up complex view logic with the help of presenters, and doing this from scratch gives you a lot of flexibility. Here I show not only how to create presenters, but how to test them using Test Unit and RSpec.

Comments (6):

By anonymous    2017-09-20

The issue is that actionview-related methods are not available to POROs.

In order to get all the great stuff from actionview: you need to utilize the view_context keyword. Then: you can simply call upon actionview-related methods from your view_context:

class BuildLink
  attr_accessor :blog, :view_context

  def initialize(blog, view_context)
    @blog = blog
    @view_context = view_context
  end

  def some_method
    content_tag(:li, link_to(“Show Blog“, view_context.blog_path(blog)))
  end
end

So for example: from your controller you would call upon this PORO like so:

BuildLink.new(@blog, view_context).some_method

For more information, see below references:

Original Thread

By anonymous    2017-09-20

Personally, I use the presenter pattern in a case like this. So, in your controller you would do something like:

def user 
  @user = user.find_by(:id => params[:id])
  @user_presenter = UserPresenter.new(self)
end

Then in your view you would do something like:

<h1><%= @user.name %>'s Friends List</h1>
@user_presenter.friends_list

I like doing it this way because:

  • My views have zero knowledge about my model layer (I like the separation)
  • It makes my views super-dumb (no logic in the view, which I prefer - in my apps, views have only html mark up (I use HAML) and calls to presenters)
  • If I make any changes to my models, I don't have to go back into my view and make changes (as long as my UserPresenter honors the friends_list interface)
  • I find it a whole lot easier to test plain old ruby objects (all my Presenters are POROs) than testing various Rails components (controllers, views, etc.)

There is a good RailsCast on Presenters.

Original Thread

By anonymous    2017-09-20

You're closer than you think! But, it looks to me like you're heading toward the Presenter pattern - not the Helper pattern. Check out RailsCast for a better discussion.

So, let's say you have something like:

app/presenters/posts/show_presenter.rb

class Posts::ShowPresenter

    def initialize(controller)
      @controller = controller
    end

    def newer_link
      link_to 'newer', post_path(newer_post)
    end

    def older_link
      link_to 'older', post_path(older_post)
    end

  private

    def controller()          @controller                             end
    def params()              controller.params                       end
    def view_context()        controller.view_context                 end

    def newer_post
      Post.where(['id > ?', post.id]).last
    end

    def older_post
      Post.where(['id < ?', post.id]).first
    end    

    def post
      get_controller_variable(:post)
    end

    def get_controller_variable(sym)
      controller.instance_variable_get("@#{sym}")
    end

    def method_missing(*args, &block)
      view_context.send(*args, &block)
    end

end

Now, let's say in your PostsController, you do something like:

class PostsController < ApplicationController

  def show
    @post = Post.find_some_clever_way
    @presenter = Posts::ShowPresenter.new(self)
    ...
  end

end

In your partial, you should now be able to do something like:

<ul>
  <li><%= @presenter.older_link %></li>
  <li><%= @presenter.newer %></li>
  <li><%= link_to 'show all', posts_path %></li>
</ul>

Most of the magic lies in that method_missing definition. It basically allows your presenter to use the view_context from the controller to do things like render link_to and generate post_path.

Original Thread

Popular Videos 0

Submit Your Video

If you have some great dev videos to share, please fill out this form.