Guest User

Untitled

a guest
Feb 22nd, 2019
74
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