Help me figure out how to display form validation errors using gem Reform . I could not think of anything else but how to use notice as the output of validation errors.
The problem is that if the form does not pass validation - the current state of the form is not saved (example in the picture). That is, if the form contains 20 fields and the user made a mistake in one thing - he will have to refill the form again. And this is not correct.
The documentation on this issue could not find anything.
Form-object:
class AddressForm < Reform::Form include Reform::Form::ActiveModel include Reform::Form::ActiveModel::FormBuilderMethods model :address property :first_name property :last_name property :address property :city property :country_id property :zipcode property :phone extend ActiveModel::ModelValidations copy_validations_from Address end Controller:
class Users::ProfilesController < ApplicationController before_action :authenticate_user! before_action :set_user before_action :create_form, only: [:update, :edit] def edit end def update form = AddressForm.new(address_type) if form.validate(params_type) form.save redirect_to edit_profile_path else render :edit, notice: form.errors.full_messages end end def address_type return Address.find(@user.billing_address) if params[:billing] return Address.find(@user.shipping_address) if params[:shipping] end def params_type return params[:billing] if params[:billing] return params[:shipping] if params[:shipping] end private def set_user @user = current_user end def profile_params params.require(:user). permit(:email, :password, :password_confirmation, :current_password) end def create_form @address_form = AddressPresenter.new(@user) end end Presenters
class AddressPresenter include ActiveModel::Model attr_reader :billing_form, :shipping_form def initialize(user) @user = user @billing_form = AddressForm.new(address('billing')) @shipping_form = AddressForm.new(address('shipping')) end private def address(type) address_id = eval("@user.#{type}_address_id") address_id ? Address.find(address_id) : Address.new end end View
.row .col-md-6 = form_for @address_form.billing_form, as: :billing, url: {action: 'update'} do |f| %h3= t('checkout.billing_address') %hr.style3 = render 'static/error_messages', target: @address_form.billing_form = render 'address/form', f: f = f.submit t('page.save_button'), class: 'btn btn-primary' .col-md-6 = form_for @address_form.shipping_form, as: :shipping, url: {action: 'update'} do |f| %h3= t('checkout.billing_address') %hr.style3 = render 'static/error_messages', target: @address_form.shipping_form = render 'address/form', f: f = f.submit t('page.save_button'), class: 'btn btn-primary' Update
I do not understand what the problem is, but if you do everything strictly along the docks, remove the presenters and for one form, everything works — both validation and change of form.
Modified controller code:
class Users::ProfilesController < ApplicationController before_action :authenticate_user! before_action :set_user def billing_address @user.billing_address || Address.new end def edit # сюда приходят предзаполненные данные @billing_address ||= AddressForm.new(billing_address) end def update form = AddressForm.new(billing_address) if form.validate(params[:billing]) form.save redirect_to action: :edit else render :edit end end private def set_user @user = current_user end end View
= form_for @billing_address, as: :billing, url: {action: 'update'} do |f| %h3= t('checkout.billing_address') %hr.style3 = render 'static/error_messages', target: @billing_address = render 'address/form', f: f = f.submit t('page.save_button'), class: 'btn btn-primary' 
attr_reader :billing_form, :shipping_form, or delete the constructor and the class inherit fromStruct.new(:billing_form, :shipping_form). - anoamupdatemethod in the formform = choose_formold data is written. Although new screen debugs come toparams- Alexandr Dmitrenkoupdatemethod the old data comes in theform(pre-filled) - Alexandr Dmitrenko