I am battling an error with nested attributes and trying to fix the cop error at the same time. So here is the walk through. A coupon code may be submitted with the form using nested attributes that may affect the price of the job. This only occurs if the coupon code is valid. In this scenario the coupon code has already been assigned so the first if coupon_code && coupon.nil?
is triggered. When the form comes back around the flash message works correctly but simple form does not display the value. I could adjust simple form to have the value with an instance variable but I'm starting to smell something a bit off here in my logic. Also, the smell of Assignment Branch Condition
is starting to worry me. I can move forward with this, but the user would like to see the code. I would too.
Cop Error:
app/controllers/payments_controller.rb:9:3: C: Assignment Branch Condition size for update is too high. [17.97/15]
Controller:
class PaymentsController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :route_not_found_error
Numeric.include CoreExtensions::Numeric::Percentage
def update
@job = Job.find(params[:job_id])
coupon_code = params[:job][:coupon_attributes][:code]
coupon = validate_coupon(coupon_code)
if coupon_code && coupon.nil?
@coupon_code = coupon_code
flash.now[:error] = t('flash_messages.coupons.id.not_found')
render 'payments/new', layout: 'nested/job/payment'
else
update_job(@job, coupon)
update_coupon(coupon, @job) if coupon
redirect_to @job.vanity_url
end
end
def new
@job = Job.find(params[:job_id])
return if reroute?(@job)
render 'payments/new', layout: 'nested/job/payment'
end
private
def update_job(job, coupon)
job.start_at = DateTime.now
job.end_at = AppConfig.product['settings']['job_active_for_day_num'].days.from_now
job.paid_at = DateTime.now
job.price = price_job(coupon)
# job.save
end
def validate_coupon(coupon_code)
return nil unless coupon_code.present?
coupon = Coupon.active.find_by_code(coupon_code)
return nil unless coupon.present?
coupon
end
def price_job(coupon)
price = AppConfig.product['settings']['job_base_price']
return price unless coupon
price = coupon.percent_discount.percent_of(price)
price
end
def update_coupon(coupon, job)
coupon.job_id = job.id
coupon.executed_at = DateTime.now
coupon.save
end
end
View:
ruby:
content_for :body_id_class, 'PaymentNew'
content_for :js_instance, 'viewPaymentNew'
content_for :browser_title, 'Payment'
job_base_price = AppConfig.product['settings']['job_base_price']
coupon_code = @coupon_code ||= ''
= simple_form_for(@job, url: job_payment_path, html: { id: 'payment-processor-form' }) do |j|
div[class='row']
div[class='col-md-12']
div[class='panel panel-default']
div[class='panel-heading']
h3[class='panel-title']
|Total Cost
div[class='panel-body']
h2[class='job-cost' data-initial = "#{job_base_price}"]
= number_to_currency(job_base_price)
div[class='panel-heading']
h3[class='panel-title']
|Have a coupon?
div[class='panel-body']
div[class='row-inline']
div[class='row-block row-block-one']
= j.simple_fields_for :coupon_attributes, @job.coupon do |c|
= c.input_field :code, maxlength: 50, id: 'coupon-code', class: 'form-control', data: { 'initial' => 0 }, value: coupon_code
div[class='row-block']
button[type='button' class='btn btn-primary' id='coupon-verify' ]
|Verify
p[class='help-hint']
= t('simple_form.hints.coupon.code')
div[class='row']
div[class='col-md-12']
= j.button :button, type: 'button', class: 'btn-primary text-uppercase', id: 'purchase-job' do
= job_posting_button_step_label
Updates
- Refactoring this code to work with the post below. Factories fixed factorygirl create model association NoMethodError: undefined method