Reputation: 29088
Please, I really don't know how best to achieve refactoring this code following the best rails practices. I am trying to call some methods that are defined in a model in my rails application in a different controller.
I have a Donations model and a Dashboard Controller and I would like to display some data about donations on the dashboard. I want to achieve this by defining the data that I want in some methods and scopes in the Donations model and then call them in the Dashboard controller and then make them available in the *Dashboard views**.
But I realized that no data about donation gets displayed on the dashboard, which may be as a result of the fact that the methods in the Donations model doesn't get exposed or are not available to the Dashboard controller when they are called, since they are a different model and different controller.
Here is my code
Donations Model
class Donation < ApplicationRecord
belongs_to :program
scope :paid_count, -> { where(payment: true).count }
scope :unpaid_count, -> { where(payment: false).count }
scope :paid_sum, -> { where(payment: true).sum(:amount) }
scope :deployed_sum, -> { where(deployment: true).sum(:amount) }
scope :not_deployed_sum, -> { where(deployment: false, payment: true).sum(:amount) }
def self.deployed_donations_percent
(deployed_sum.to_f / paid_sum.to_f) * 100
end
def self.not_deployed_donations_percent
(not_deployed_sum.to_f / paid_sum.to_f) * 100
end
end
Dashboard Controller
class DashboardController < ApplicationController
def index
# Paid Donations in Chart
@paid_donations = Donation.paid_count
# Unpaid Donations in Chart
@unpaid_donations = Donation.unpaid_count
# Total Donations Sum
@total_donations_sum = Donation.paid_sum
# Deployed Donations
@deployed_donations = Donation.deployed_sum
# Not Deployed Donations
@not_deployed_donations = Donation.not_deployed_sum
# Deployed Donations Percentage
@deployed_donations_percent = Donation.deployed_donations_percent
# Not Deployed Donations Percentage
@not_deployed_donations_percent = Donation.not_deployed_donations_percent
@total_donations = Donation.count
# Paid Donations
@paid_donations = Donation.paid_count
# Unpaid Donations
@unpaid_donations = Donation.unpaid_count
# All Programs
@programs = Program.all
end
end
Dashboard Index
<h2>
DASHBOARD
</h2>
<h4>Overall Donations</h4>
<%#= area_chart @donations.map { |pay|{name: pay.payment, data: @donations.where(payment: pay).group_by_day(:created_at).count}}, discrete: true %>
<%= line_chart Donation.group(:payment).group_by_day(:created_at).count
<h4>Total Donations</h4>
<%= number_with_delimiter(@total_donations_sum, :delimiter => ',') %>
<h4>Deployed</h4>
<%= number_with_delimiter(@deployed_donations, :delimiter => ',') %>
<div>
<%= @deployed_donations_percent.round %>>
</div>
<h4>Undeployed</h4>
<%= number_with_delimiter(@not_deployed_donations, :delimiter => ',') %>
<div>
<%= @not_deployed_donations_percent.round %>
</div>
<h4>Total Donations</h4>
<header>
<%= @total_donations %>
</header>
<h4>Paid Donations</h4>
<header>
<%= @paid_donations %>
</header>
<h4>Unpaid Donations</h4>
<header>
<%= @unpaid_donations %>
</header>
PROGRAMS
<td>Program Name</td>
<td>Sponsored</td>
</tr>
<% @programs.each do |program| %>
<tr>
<td><%= program.name %></td>
<td><%= program.donations.count %></td>
Please, I would greatly appreciate some help on how to refactor this code and get the Donations model methods exposed to the Dashboard Controller. Thank you.
Upvotes: 0
Views: 719
Reputation: 103
You can also try this out.
Controllers and models have a folder called concerns where you can keep codes that you want to be shared by different controllers and/or models.
Simply move the code that you want to share to the concerns folder, and then call them on each model.
You can define the code in the concerns folder using modules.
Upvotes: 1
Reputation: 29088
Finally, I got it to work.
I needed to implement service objects using Plain Old Ruby Objects. For each for the actions, I placed them in a separate service, and then called them in the controllers.
The steps are
That's all.
Upvotes: 0