Mike Coutermarsh
code @producthunt
Medium.com’s user profile shows all of the users posts, their followers and what they have highlighted.
I’d imagine their data model works like this. They have a User model, a Post model, a FollowerAssociationModel and a Highlights model.
For their profile page, they bring in data from several different sources.
When building out a users profile page in your app, it might feel tempting to create an entirely new model for it. But I'm generally very wary of creating a model for something so non-specific. It can quickly become a general "throw everything here" model.
The best way I have found to do this in Rails is to use the View Object Pattern (aka Presenter Object). You can read more about it here: 7 Patterns to Refactor Fat ActiveRecord Models (search view object).
First, you'd create a class that encapsulates all the data you want shown on the profile page.
Something like this:
class UserProfile
attr_reader :user
def initialize(user)
@user = user
end
def tagline
# example of some html conversion
@tagline ||= ConvertTagsToLinks.run(user.tagline)
end
def posts
@posts ||= user.posts.order_by_featured_date
end
def followers
@follows ||= user.followers.ordered_by_popularity
end
## ect...
end
(a bit of a contrived example, but hopefully you get the idea)
Then this makes it really easy to have one nice clean object to access in your controllers and views.
# some controller
def show
@user = User.find(params[:id)
@user_profile = UserProfile.new(@user)
# render a view...
end
Then in your view, you are able to easily access your view object.
<p class="tagline"><%= @user_profile.tagline %></p>
Using this pattern keeps your abstractions very explicit. This pattern is easy to write tests for and helps keep User Profile code out of your models.
Give it a try and let me know how it works out for you.