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

Validation errors on nested forms #32

Open
bramj opened this issue Aug 4, 2016 · 3 comments
Open

Validation errors on nested forms #32

bramj opened this issue Aug 4, 2016 · 3 comments
Labels

Comments

@bramj
Copy link

bramj commented Aug 4, 2016

Hi @andypike,

First off: thanks a lot for your work on Rectify!

So I've been rectifying a rather big, complex form and been running into some questions.
One of those is: how do you display errors on nested forms?

Take for instance the blog example again:

class Blog < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :blog
end

class BlogForm < Rectify::Form
  attribute :title, String
  attribute :posts, Array[PostForm]
end

class PostForm < Rectify::Form
  attribute :title, String
  attribute :body, String
end

Now in the view, we want to show validation errors. Typically, this is something like this:

-# app/views/blogs/_form.html.haml
- if form.errors.any?
  .alert
    %h4
      = pluralize(form.errors.count, 'error')
      prohibited this blog from being saved:
    %ul
      - form.errors.each do |key, message|
        %li= "#{key} #{message}"

Now if we have a validation error on a PostForm, this error will not be displayed, since it's in e.g. form.post.first.errors.

It's not difficult to loop over all the errors of nested models, but if you have many nested forms this becomes tedious.
Do you think it would be nice to be able to do something like form.all_errors?

@andypike
Copy link
Owner

Thanks for the question! Sorry for the delayed response but I've been away on vacation recently. Let me digest this a little and I'll get back to you. Thanks for your patience.

@scarroll32
Copy link

+1

@laurenfackler
Copy link

Here's a bit of a workaround for anyone else that might need it (thanks to @BobFromAccounting):

class ApplicationForm < Rectify::Form
  def merge_errors_for(attr, field_prefix = '')
    field_prefix = field_prefix.presence || attr.to_s

    public_send(attr.to_s).errors.messages.each do |field, errors_array|
      errors_array.each do |error_message|
        errors.add("#{field_prefix}_#{field}", error_message)
      end
    end
  end
end

class AccountForm < ApplicationForm
  attribute :name, String
  attribute :monthly_price, Integer
  attribute :office, OfficeForm
  attribute :user, UserForm

  validates :name, :monthly_price, :max_employees,
              presence: true
  validate :office_form_is_valid
  validate :user_form_is_valid

  private

  def office_form_is_valid
    if office.invalid?
      merge_errors_for(:office)
    end
  end

  def user_form_is_valid
    if user.invalid?
      merge_errors_for(:user, 'owner')
    end
  end
end

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

No branches or pull requests

4 participants