Skip to content

Instantly share code, notes, and snippets.

@derekprior
Last active January 7, 2021 00:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derekprior/9847441 to your computer and use it in GitHub Desktop.
Save derekprior/9847441 to your computer and use it in GitHub Desktop.
An idea for a a basic form object that is for aggregating data on several models
class Registration < AggregateForm
component :user, :email, :password
component :profile, :zip
validate_components :promote_errors
validate # whatever else you want
end
# This would give you
# * email, password, zip attrs
# * memoized `user` initialized from :email and :password attrs
# * memoized `profile` initialized from :zip
# * save that:
# * is wrapped in `if valid?`
# * opens a transaction (dependency on Active Record? Overrideable somehow?)
# * calls save! on user followed by profile (order determined by order of component declaration)
# * validations delegated to the component objects with errors promoted to the form object
# * smart enough to move to base if the errored field isnt on the form object?
# * other option `message: 'Problem'` uses a static message when the validations fail on the children. Useful?
# Problems:
# * How do I know how to initialize profile? I might want user.build_profile rather than Profile.new
# * Maybe you just override the default method to use something other than `new`?
# * Maybe reflect on the objects to determine the relationships? (eww)
# * What about has_many relationships?
@derekprior
Copy link
Author

another possible class level declaration:

masquerade_as :user

That would do:

def model_name
  User.model_name
end

So the users controller could still automatically be used by form_for. Would also use the user translations for all fields which might be bad....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment