I'd been doing some thinking about simplifying the display of records in Rails applications and fortunately came across show_for.
show_for
is a formtastic-like approach to displaying details about database records. It helps you DRY up your views and can even reflect on associations with code like this:
<% show_for @user do |u| %>
<%= u.attribute :name %>
<%= u.attribute :nickname, :in => :profile %>
<%= u.attribute :confirmed? %>
<%= u.attribute :created_at, :format => :short %>
<%= u.attribute :last_sign_in_at, :if_blank => "User did not access yet",
:wrapper_html => { :id => "sign_in_timestamp" } %>
<% u.attribute :photo do %>
<%= image_tag(@user.photo_url) %>
<% end %>
<%= u.association :company %>
<%= u.association :tags, :to_sentence => true %>
<% end %>
But since I'm working on an application which uses stonewall (which allows you to limit the display of a record's details), I needed the 2 of them to work together.
stonewall
allows you to guard the display of your data from your models:
stonewall do |s|
s.varies_on :aasm_state
s.guard_attribute :secret_cultivation_details
# ... role details here
end
It provides a allowed?
method which you can use to ask an object if the current user is allowed to see the content.
So I quickly put together show_for_stonewall which will limit the display of certain fields if stonewall prevents it. It was as simple as using alias_method_chain
to check that an attribute is not allowed
!allowed?(@object, current_user, attribute_name)
You can edit your show_for
translation yaml and add a redacted
key for the content to display if a field is not allowed for the current user.