Skip to content

Instantly share code, notes, and snippets.

@andypike
Created February 13, 2016 19:43
Show Gist options
  • Save andypike/eb9a78039fdf11151053 to your computer and use it in GitHub Desktop.
Save andypike/eb9a78039fdf11151053 to your computer and use it in GitHub Desktop.
Notes and experiments for the view objects in Rectify
<!--
In the template just use the @view object and call it's methods to clean up
the presentation logic. Maybe think about adding a helper method called `view`
that just returns `@view` so we can remove the noise of the `@`.
-->
<%= @view.users.each do |user| %>
<%= @view.user_link(user) %>
<% end %>
Logged in as <%= @view.logged_in_name %>
class UsersController < ApplicationController
before_action :authenticate!
def index
# Create a view object with some initial data
@view = UsersListView.new(self).data(
:users => User.active,
:stats => Stat.all
)
# Add/update data for a view object after it's been created
@view.data(:more => "hello")
@view.a = "b"
Command.call do
# `expose` should check for a `@view` instance variable, if that
# exists and it responds to #data, do `@view.data(:a => "b")` otherwise
# keep same behaviour of setting `@a = "b"`
# Another option, rather than relying on the instance variable being called
# @view, find an instance variable of type `Rectify::View` as there should
# only be one per action. This allows the developer to use any name for
# the view object
on(:ok) { expose(:a => "b") }
end
end
private
def authenticate!
@current_user ||= User.find(session[:user_id])
end
def current_user
@current_user
end
helper :current_user
end
# Pass the controller to the view constructor.
# Use method missing to delegate calls to the `controller.view_context`
# so we can access all the normal view helper methods
class UsersListView < Rectify::View
def user_link(user)
link_to "Edit #{user.name}", edit_user_path(user)
end
def logged_in_name
return "Guest" unless current_user
current_user.name
end
end
@tombeynon
Copy link

Looking great man. I was thinking of something along the same kind of lines. Single object exposed to the view is definitely the way to go, had facades in mind instead of views purely because of the directory clash but I prefer the brevity of view..

I think exposing the view instance variable through a helper method is a good idea, which means you can define the naming convention too. You might then need to provide an 'empty' View object if one isn't defined, but the user would more likely define an ApplicationView that provided methods for the layout etc, and each view can inherit from. Your expose command then becomes a lot simpler.

Now another thing that seems quite tightly linked is the concept of object presenters. I think it's separate from the view object, but one of the main concerns for a view/facade seems to be to expose presenters, and actually in your example of UsersListView, I would move at least some of that into a presenter. I think we could define some form of convention here too, but appreciate that Rectify tries to be very lightweight so maybe that's taking it too far. Also have you thought much about the coupling of a partial to a ruby class, as Cells does? Interested in your thoughts on that, I'm a bit undecided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment