ruby on rails - How do I refactor this object to lessen dependency on callbacks? -
i have order object belongs_to billingaddress , shippingaddress. want present user shippingaddress fields , checked checkbox indicating billing address matches shipping address. if user unchecks box, billingaddress fields appear.
my implementation feels clunky , order object has lot of callbacks.
class order < activerecord::base attr_accessor :bill_to_shipping_address belongs_to :billing_address, class_name: 'address' belongs_to :shipping_address, class_name: 'address' accepts_nested_attributes_for :billing_address, :shipping_address after_initialize :set_billing_to_shipping_address before_validation :set_billing_address after_validation :clear_billing_address_errors # init object option checked def set_billing_to_shipping_address self.bill_to_shipping_address ||= '1' end # copy shipping address attrs billing address def set_billing_address self.billing_address = self.shipping_address if bill_to_shipping_address? end def bill_to_shipping_address? bill_to_shipping_address == '1' end # if shipping address matches billing, copy attrs, , duplicate errors too. # need show user 1 set of errors if addresses same, remove them billing address. def clear_billing_address_errors if bill_to_shipping_address? self.errors.messages.each { |k,v| self.errors.messages.delete(k) if k.to_s.split('.')[0] == 'billing_address' } end end end i have 4 methods along 3 registered callbacks satisfy need. i'm hacking around error messages. have no logic in controller , form relatively simple.
= form_for @order |f| # ... = f.label :bill_to_shipping_address, class: 'checkbox' #{f.check_box :bill_to_shipping_address} use shipping address billing address. questions:
- how can improve implementation?
- would switching relationships help?--
order has_one :billing_address,has_one :shipping_addressinstead ofbelongs_to. nested forms feel more natural; in that, parent creates children, not other way around.
i'm reading fair bit of refactoring books, can never map examples own object design. i'm not experienced guess. i'm using rails 4.
if checked 'billing address same shipping address', shouldn't try validate or save separate billing address, , therefore shouldn't have validation errors.
since form submit creating multiple models, i'd suggest separate orderbuilder service object (there might better name) call controller. way order model doesn't need concerned clearing address errors. order builder can take care of creating order , address records, or copying on shipping address billing address fields.
also, 'bill_to_shipping' should boolean in database. if need converting of params boolean, @ time you're saving record, not every time database.
Comments
Post a Comment