In my Rails 7 app I've got data table which I want to decorate. The data comes from the API response so in fact it's an array of hashes. Like below:
# transactions_controller.rb
class TransactionsController < ApplicationController
def index
response = client.transactions.list(platform_id: current_user.platform_id, page: 1, per_page: 100)
@transactions = response.body['data']
end
private
def client
@client ||= TestAPI::Client.new
end
end
Now inside the transactions/index.html.erb I've got a table with @transactions
data which I want to decorate:
#views/transactions/index.html.erb
<table >
<thead>
<tr>
<b>
<tr>
<th>Date</th>
<th>Amount</th>
</tr>
</b>
</tr>
</thead>
<tbody>
<% @transactions.map do |transaction| %>
<tr>
<td>
<%= transaction['created_at'] %>
</td>
<td>
<%= transaction['amount_cents'] %>
</td>
</tr>
<% end %>
</tbody>
</table>
I know I could inject that logic inside of view file to be like:
(...)
<td>
<%= Date.parse(transaction['created_at']).strftime("%d.%m.%Y") %>
</td>
<td>
<%= "#{ transactions_data.last['amount_cents']/100}" "#{ transactions_data.last['currency']}" %>
</td>
(...)
But I want to get rid of that logic from the view since I'll have more and more logic in the future here.
CodePudding user response:
Kudos for wanting to remove logic from the view.
You need a new object, it could be called TransactionPresenter
or whatever you choose. It will implement the view logic. So in your TransactionsController
:
def index
response = client.
transactions.
list(platform_id: current_user.platform_id, page: 1, per_page: 100).
map{|t| TransactionPresenter.new(t)}
@transactions = response.body['data']
end
and the TransactionPresenter
model could be something like this:
class TransactionPresenter
def initialize(transaction)
# capture the fields of interest as variables
end
def amount
"$#{amount_cents.to_f/100}" # for example, whatever makes sense in your context
end
end
so all logic is removed from the view:
<table>
<% @transactions.each do |transaction| %>
<tr><%= transaction.amount %></tr>
<% end %>
</table>