SHARE
TWEET

Untitled

a guest Feb 22nd, 2019 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module MiniForm::Associations
  2.   extend ActiveSupport::Concern
  3.  
  4.   included do
  5.     validate do
  6.       associations.validate_into(errors)
  7.     end
  8.  
  9.     after_update do
  10.       association.save
  11.     end
  12.   end
  13.  
  14.   module ClassMethods
  15.     # association :model, :name, attributes: %i(id name for)
  16.     # TODO: single assoc
  17.     # TODO(rstankov): validate values
  18.     # TODO options: allow_new, allow_destroy
  19.     def association(model_name, association_name, attributes:, allow_new: true, allow_destroy: true)
  20.       define_method(association_name) do
  21.         public_send(model_name).public_send(association_name)
  22.       end
  23.  
  24.       define_method(association_name) do |values|
  25.         associations.assign(public_send(model_name).public_send(association_name), values)
  26.       end
  27.     end
  28.   end
  29.  
  30.   private
  31.  
  32.   def associations
  33.     @associations ||= Associations.new
  34.   end
  35.  
  36.   class Associations
  37.     def initialize
  38.       @to_save ||= []
  39.     end
  40.  
  41.     def assign(assoc, values)
  42.       record = assoc.detect { |r| r.id === values[:id] } if values[:id]
  43.       record ||= assoc.new
  44.  
  45.       if values[:_destroy]
  46.         record.marked_for_destruction
  47.       else
  48.         record.attributes = values
  49.       end
  50.  
  51.       to_save << record
  52.  
  53.       record
  54.     end
  55.  
  56.     def validate_into(errors)
  57.       to_save.reject(&:marked_for_destruction).select(&:invalid).each do |record|
  58.         # TODO(rstankov): ADD errors
  59.         errors.add :todo, :invalid
  60.       end
  61.     end
  62.  
  63.     def save
  64.       to_save.each do |record|
  65.         if record.marked_for_destruction?
  66.           record.destroy!
  67.         else
  68.           record.save!
  69.         end
  70.       end
  71.     end
  72.  
  73.     private
  74.  
  75.     attr_reader :to_save
  76.   end
  77. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top