trailblazer / reform

Form objects decoupled from models.
https://trailblazer.to/2.1/docs/reform.html
MIT License
2.49k stars 184 forks source link

Using a nested form with populator. #538

Closed shettytejas closed 2 years ago

shettytejas commented 2 years ago

I have two contracts:

  1. Signup

    class Auth::Contracts::Signup < Reform::Form
    property :first_name, required: true
    property :last_name, required: true
    property :username, required: true
    property :user_auth_detail, required: true, populator: ->(_) { self.user_auth_detail = UserAuthDetail.new } do
    property :email, required: true
    property :password, required: true
    
    validates :email, 'valid_email_2/email': { disposable: true }, unique: true
    end
    
    validates :username, unique: true
    end
  2. Update

    class Auth::Contracts::Update < Reform::Form
    property :email, required: true
    property :password, required: true
    
    validates :email, 'valid_email_2/email': { disposable: true }, unique: true
    end

You could see that the populator of the Signup form has the same code which is already available in the Update form. Is there a way I could use the Update form directly with the populator? I've tried playing around with the code, but then the validation of the nested form weren't taking place.

Any help with this would be nice 😄

yogeshjain999 commented 2 years ago

@Shetty-Tejas Did you try nesting explicit form ?

property :user_auth_detail, form: Auth::Contracts::Update, ...

https://trailblazer.to/2.1/docs/reform.html#nesting-explicit-form

shettytejas commented 2 years ago

@yogeshjain999 yea I did. I replaced the populator with the form as stated above, but then I was getting the "Your :populator did not return a Reform::Form instance for user_auth_detail." error.

shettytejas commented 2 years ago

Update: I tried adding the form with the populator and it's defo not throwing any errors and the tests are passing. So looks like this worked 😄 Thanks Yogesh 👍🏾

property :user_auth_detail, required: true, form: Auth::Contracts::Update, populator: ->(_) { self.user_auth_detail = UserAuthDetail.new }