Hi Upcase community,
I am a beginner and asking for any suggestion on refactoring. Trying to follow Sandi Metz’s rule but I can’t figure out how to reduce this class under 100 lines of code with limited knowledge that I have.
Basically, it is a donations controller that is charging stripe payments.
There are four things this class is trying to achieve:
New Stripe Customers
- New customer donate one time gift
- New customer donation monthly recurring gift
Existing Stripe Customer
3) Existing customer donates one time gift
4) Existing customer donates monthly recurring gift
Everything is working as it should, but as you can see the code is very long…
Any tips and help will be greatly appreciated to become a better coder!
Thanks in advance!
Here is the code in Gist: http://goo.gl/Y4gjUE
class DonationsController < ApplicationController
def index
end
def new
end
def create
monthly_donation_with_existing_stripe_customer
one_time_donation_with_existing_stripe_customer
monthly_donation_with_new_stripe_customer
one_time_donation_with_new_stripe_customer
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to donations_path
end
private
def stripe_email_present
Payment.where(:email => params[:stripeEmail]).present?
end
def stripe_email_blank
Payment.where(:email => params[:stripeEmail]).blank?
end
def monthly_donation_checked
params[:monthlyDonation] == "1"
end
def monthly_donation_not_checked
params[:monthlyDonation] == nil
end
def monthly_donation_with_existing_stripe_customer
if stripe_email_present && monthly_donation_checked
create_stripe_plan
create_stripe_subscription_to_existing_customer
create_stripe_payment_without_email
redirect_to @payment
end
end
def one_time_donation_with_existing_stripe_customer
if stripe_email_present && monthly_donation_not_checked
charge_existing_stripe_customer
create_stripe_payment_without_email
redirect_to @payment
end
end
def monthly_donation_with_new_stripe_customer
if stripe_email_blank && monthly_donation_checked
create_stripe_customer
create_stripe_plan
create_stripe_subscription_to_new_customer
create_stripe_payment_with_email
redirect_to @payment
end
end
def one_time_donation_with_new_stripe_customer
if stripe_email_blank && monthly_donation_not_checked
create_stripe_customer
charge_new_stripe_customer
create_stripe_payment_with_email
redirect_to @payment
end
end
def create_stripe_customer
@customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:card => params[:stripeToken]
)
end
def charge_new_stripe_customer
@charge = Stripe::Charge.create(
:customer => @customer.id,
:amount => params[:amount].to_i * 100,
:description => 'Thrive General Donation',
:currency => 'usd'
)
end
def charge_existing_stripe_customer
@payment_donor = Payment.find_by_email(params[:stripeEmail])
@charge = Stripe::Charge.create(
:customer => @payment_donor.customer_id,
:amount => params[:amount].to_i * 100,
:description => 'Thrive General Donation',
:currency => 'usd'
)
end
def create_stripe_plan
@stripe_plan = Stripe::Plan.create(
:amount => params[:amount].to_i * 100,
:interval => 'month',
:name => params[:stripeName] + ' ' + 'Online Monthly Donation' + ' - ' + params[:stripeEmail],
:currency => 'usd',
:id => SecureRandom.hex
)
end
def create_stripe_subscription_to_existing_customer
@existing_customer = Payment.find_by_email(params[:stripeEmail])
customer = Stripe::Customer.retrieve(@existing_customer.customer_id)
customer.subscriptions.create(:plan => @stripe_plan.id)
end
def create_stripe_subscription_to_new_customer
customer = Stripe::Customer.retrieve(@customer.id)
customer.subscriptions.create(:plan => @stripe_plan.id)
end
def create_stripe_payment_without_email
@existing_customer_from_db = Payment.find_by_email(params[:stripeEmail])
@payment = Payment.create(
amount: params[:amount],
card: params[:stripeToken],
currency: 'usd',
customer_id: @existing_customer_from_db.customer_id,
description: 'Thrive Online Donation',
monthly_donation: params[:monthlyDonation],
uuid: SecureRandom.uuid
)
end
def create_stripe_payment_with_email
@payment = Payment.create(
amount: params[:amount],
card: params[:stripeToken],
currency: 'usd',
customer_id: @customer.id,
description: 'Thrive Online Donation',
email: params[:stripeEmail],
monthly_donation: params[:monthlyDonation],
uuid: SecureRandom.uuid
)
end
end
Here is the form code on my donation view page:
<%= form_tag donations_path, id: 'chargeForm' do %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<div class="input-group">
<%= text_field_tag :amount, params[:amount], :class => 'donation-amount-number-only' %>
<%= hidden_field_tag 'stripeToken' %>
<%= hidden_field_tag 'stripeEmail' %>
<%= hidden_field_tag 'stripeName' %>
<br />
<br />
<span class="input-group-btn">
<button id="btn-buy" type="button" class="btn btn-block btn-donate">Donate</button>
</span>
</div>
<p>
<%= check_box_tag :monthlyDonation %>
<%= label_tag(:monthlyDonation, "Recurring Monthly Donation") %>
</p>
<script>
var handler = StripeCheckout.configure({
key: '<%= Rails.configuration.stripe[:publishable_key] %>',
token: function(token, arg) {
document.getElementById("stripeToken").value = token.id;
document.getElementById("stripeEmail").value = token.email;
document.getElementById("stripeName").value = token.card.name;
document.getElementById("chargeForm").submit();
}
});
document.getElementById('btn-buy').addEventListener('click', function(e) {
handler.open({
address: true,
amount: document.getElementById("amount").value * 100,
currency: 'usd',
description: 'Donation to Thrive',
name: 'Thrive Ministry',
panelLabel: 'Donate {{amount}}',
image: 'assets/logo-thrive-stripe.jpg'
});
e.preventDefault();
})
</script>
<% end %>
Thank you for your help!