Code Review
Hello Everyone, I have reviewed a codebase of one of our projects. It was a good experience.
Few good things.
- Really clean code.
- Small methods.
- I had to travel 5 months back commits to find some bad code. :)
Things to improve on:
- Found less specs, But it is possible that specs have been covered already.
Overall Thoughts:
The code is super clean, liked it!. fantabulous work folks!
Snippets:
Code:
Menu.pluck(:hyphenated_name)
Suggestion:
This can be moved to class method which can be cached instead of firing the queries in the app again and again, one problem with this approach is that we need to reload the cache when a new menu is added, which can be done through Menu callbacks.
ex:
class Menu def self.cached_hyphenated_names @hyphenated_names ||= Menu.pluck(:hyphenated_name) end end
Code:
before(:all) do Menu.delete_all generate_menus end
Suggestion:
Should Avoid .delete_all in specs. These kind of stuffs make our specs unstable and we are forced to maintain the before all block for the specs that we will add in the future. We can use cleaner gem to avoid this delete_all calls.
Code:
if current_order current_order.calculate_shipping_cost_and_shipping_tax update_guest_user_email_and_create_order_billing_address stripe_card_token = params[:stripe_card_token] customer = create_stripe_customer(stripe_card_token) @order = Order.find(current_order.id).decorate @order.update_order(customer) @order.delete_shipments_without_item params[:coupon_code].present? && update_discount_coupon current_order.checkout else redirect_to carts_path end
Suggestion:
Move methods to AR callbacks if possible, and test them in specs.
4)
Code:
def create if !current_user.default_address params['address']['is_default'] = true end super end
Suggestion:
I see that we are using inherited_resources, but we are not using it to its full potential.
This can be done this way too. Also, note I have used the return value of .blank? as assignment for is_default.
def create resource.is_default = current_user.default_address.blank? super end
Code:
file = "#{Rails.root}/config/order_confirmation_email.yml" seller_email = YAML.load_file(file)[Rails.env]["seller_email"]
Suggestion:
I saw this code were called inside the perform method of Job. Ideally it should be present outside of the JOB and should be accessed as constants
Code:
UserMailer.new.charged_successfully_notification_for_seller(seller_email, amount, customer_name, email, order_number).deliver
Suggestion:
There is a huge argument dependency here, I need to remember the order of the arguments and number of arguments that needs to passed to method. We need to change the code something similar to this.
UserMailer.new.charged_successfully_notification_for_seller( seller_email: seller_email, amount: amount, customer_name: customer_name, email: email, order_number: order_number ).deliver
By changing the code this way, I dont need to remember the order.
Its generally not recommended to have more than two arguments for a method
Code:
module ActiveAdmin class ResourceDSL def filter(*args) field = args[0] klass = @config.resource_class_name.constantize type = klass.columns.select{|c| c.name == field.to_s}.first.try(:type) if type == :datetime controller do before_filter only: :index do unless params["q"].blank? gte = params["q"]["#{field}_gte"] lte = params["q"]["#{field}_lte"] params["q"]["#{field}_gte"] &&= gte.to_date.at_beginning_of_day params["q"]["#{field}_lte"] &&= lte.to_date.end_of_day end end end end super end end end
Suggestion:
unless params["q"].blank?
this is confusing. it can be written this way
if params ["q"]
whole unless block can be moved to a meaningful instance method of ResourceDSL with params as argument.
May be some of my suggestions are not suitable in some cases, Just let me know if anything can be further improved.
Thanks