draper gem
gem 'draper' in your gemfile
bundle
You generate a decorator for a specific object
bin/rails g decorator Campaign
In your config/application.rb We need to add this line so that rails will load the decorator files. By default rails will only load associated files.
config_autoload_paths << RAils.root.join("app","decorators")
app/decorators is where all your decorator files will be stored.
delegate_all
This line of code lets all the methods to be used in decor
Add
def name
@object.name.titleize
end
We add decorate to the controller file
campaigns/controller
def find_campaign
@campaign = Campaign.friendly.find(params[:id]).decorate
end
We shoud remove titleize from the view files
app/views/show.html.erb
<%[email protected] %>
to
<%[email protected] %>
In your decorator h is a helper method
def goal
h.number_to_currency object.goal
end
Formatting the end date
def end_date
h.formatted_date_time object.end_date
end
<%= @campaign.state_label%>
def state_label
h.content_tag :div, class: "label label-default" do
object.aasm_state
end
end
If you want to change the class
def state_label
bootstrap_classes = {"draft" => "label-default",
"unfunded" => "label-danger",
"published" => "label-success",
"canceled" => "label-warning"}
h.content_tag :div, class: "label #{bootstrap_classes[object.aasm_state]}" do
object.aasm_state
end
end
<% if @campaign.draft? %>
<%= link_to "Publish", campaign_publishings_path(@campaign),
method: :post,
class: "btn btn-primary",
data: {confirm: "Are you sure? You won't be able to edit the campaign after it's published."} %>
<% end %>
#Turning this into
<%= @campaign.publish_button %>
def publish_button
if object.draft?
h.link_to "Publish", h.campaign_publishings_path(object),
method: :post,
class: "btn btn-primary",
data: {confirm: "Are you sure? You won't be able to edit the campaign after it's published."}
end
end
Service Objects There isn't a standard way to use service object so we will create from scratch 1. Add new folder services ex. app/services Add new folder campaigns app/services/campaign Add new file publish_campaign.rb app/services/campaign/publish_campaign.rb 2. gem 'Virtus' 3.
config_autoload_paths << RAils.root.join("app","services")
class Campaigns::PublishCampaign
include Virtus.model
attribute :campaign, Campaign
def call
if campaign.publish!
DetermineCampaignStateJob.set(wait_until: campaign.end_date).perform_later(campaign)
true
else
false
end
end
end