Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React / Yup / Formik / GraphQL compatible #795

Closed
wants to merge 1 commit into from
Closed

React / Yup / Formik / GraphQL compatible #795

wants to merge 1 commit into from

Conversation

PascalPixel
Copy link

Please forgive this giant mess and info dump that is incompatible with your actual repo, and allow me to explain...

We use ClientSideValidations on the back-end in Rails, and we have used it on the front-end for years with UJS/jQuery. Thank you for the hard work, you made our lives easier.

Recently we've switched over to using React for some of the more complex forms, we found a form library called Formik that was helpful. They have a front-end validation built in, but this would involve needing to re-write all our model validations for their recommended API, called Yup.

Instead, we made a little file in our Rails back-end that translations your ClientSideValidations to that API/Yup format it expects, and send that as JSON over the wire.

It works well for using ClientSideValidations back-end with a React/Formik/Yup/whatever front-end.

Not to let the code go to waste, I am basically dumping it from our repo to you in this PR, in the hopes that you could somehow use this to accommodate newer Rails users who use Webpacker gem and/or some combination of a front-end framework and would like to use it with ClientSideValidations for automatic validationScheme generation from the server based on the model.

Hope this makes sense, feel free to close this PR if you find this unusable. Thank you for your efforts over the years.

@tagliala
Copy link
Contributor

tagliala commented Jun 4, 2020

Hi,

thanks for being part of the CSV community and thanks for this PR!

I was thinking about something like this for years, but I never had the chance of working on something like this.

I was also thinking to rely on a different front-end validation plugin to remove all the constraints of (dependence on jquery, promise-based approach, model-based approach)...

Question: do you need to regenerate this file after each change to the model?

@PascalPixel
Copy link
Author

Question: do you need to regenerate this file after each change to the model?

No. Currently, ClientSideValidations places the validations for a model as a JSON string on an HTML attribute on the form tag, the client side then reads this JSON and performs validations.

What we have instead, is that this same JSON string is passed over the API, and can then be used for another client-side code. In our case React with Formik.

Basically it just detaches the ClientSideValidations client-side and server-side code, keeping the server-side as-is.

Hope that makes sense...

@tagliala tagliala marked this pull request as draft June 5, 2020 07:56
@tagliala
Copy link
Contributor

tagliala commented Jun 6, 2020

Thanks, This makes perfectly sense.

I would like to create a new repo and a plugin, like the one for simple-form.

Will client_side_validations-yup work as repo name?

IMHO this is one of the most interesting approach for the future of CSV, so we can just focus on the back-end and creating a JSON object for a front-ent client-side validator.

@tagliala
Copy link
Contributor

@PascalPixel

I would like to open a new repository. Does client_side_validations-yup work?

@PascalPixel
Copy link
Author

@tagliala Sounds great! I support whatever you decide 😄

@mattboldt
Copy link

Just stumbled upon this while looking for the exact same thing! I would love to be able to inherit all my server-side validations, dump them into something like yup, and then have the option to add any that make more sense to only have client-side. Has client_side_validations-yup broken ground yet?

@tagliala
Copy link
Contributor

tagliala commented Sep 4, 2020

Hi @mattboldt, thanks for your interest.

I'm quite busy with my job, I will try at least to create and setup a new repository, but I cannot guarantee, for the moment please use this fork.

One thing is sure: I cannot provide support for this new plugin

@tagliala
Copy link
Contributor

tagliala commented Sep 4, 2020

Ok.

I've created a repo here: https://github.com/DavyJonesLocker/client_side_validations-yup

This is the only thing I can do. Feel free to make PRs against that repo

@mattboldt
Copy link

FWIW I, having a ticket to finish, implemented a version of this of my own inspired by this PR.

Main points:

  • Use CSV's resource.client_side_validation_hash to fetch all the client-side-friendly rails model validations
  • Translate this hash to Yup's schema in ruby
    • { presence: { message: "can't be blank" }}
      # translates to...
      { name: :required, options: ["can't be blank"] }
  • Map each array of validations to each attribute on the model
    • Leveraged a strong params hash in the controller where [:id, :name, :username] are permitted, therefor I should only find validations for those fields
  • Send a "Form Object" json to the client containing all fields and their validators
    • // json payload
      form: {
        name: {
          attrubute: "name",
          value: "Matt",
          type: "string", // from database column type
          input_name: "user[name]",
          validators: [{ name: "required", options: ["can't be blank"] }],
        }
      }
  • Loop thru each field & validator and dynamically build a yup schema
    • e.g. the above^^ validators array is auto-translated to...
    • yup.object().shape({
        name: yup.string().required("can't be blank")
      })
  • Do all of this recursively to support accepts_nested_attributes_for :association 🎉
    • Used Yup's array().of(object().shape({ ...nested attrs... }))

So now, to get a fully client side AND server side validated model form, you just add validations to your rails model, call a FormBuilder class in the controller, and let a custom hook generate the schema. Currently working with react-hook-form to handle form state & errors.

If I get time soon, I'll set up a PR with some of this in the client_side_validations-yup repo. Or, if the effort here has diverged a bit too much from the spirit of CSV, I may create a repo of my own that has CSV as a dependency.

@tagliala
Copy link
Contributor

@mattboldt Amazing, thanks

Map each array of validations to each attribute on the model

  • Leveraged a strong params hash in the controller where [:id, :name, :username] are permitted, therefor I should only find validations for those fields

I really like this. I think this can prevent information disclosure.

I would like to support this by default in CSV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants