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

Display detailed parent errors on childs edit page #2681

Open
y0608 opened this issue Oct 8, 2024 · 0 comments
Open

Display detailed parent errors on childs edit page #2681

y0608 opened this issue Oct 8, 2024 · 0 comments

Comments

@y0608
Copy link

y0608 commented Oct 8, 2024

  • What would you like to be able to do? Can you provide some examples?
    Show all of the errors from the parent object that happen when the child is edited (edit form).

  • How could we go about implementing that?
    What I did was override the view. I added this to app/views/admin/bank_data/_form.html.erb

  <%# Display UserDatum Errors %>
  <% if page.resource.user_datum && page.resource.user_datum.errors.any? %>
    <div id="user_datum_error_explanation">
      <h2>
        <%= t(
          "administrate.form.errors",
          pluralized_errors: pluralize(page.resource.user_datum.errors.count, t("administrate.form.error")),
          resource_name: "User Datum"
        ) %>
      </h2>

      <ul>
        <% page.resource.user_datum.errors.full_messages.each do |message| %>
          <li class="flash-error"><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
  • Can you think of other approaches to the problem?
    I can't

  • My case:
    I have 2 models: UserDatum and BankDatum.

UserDatum holds information about the user. I have a different model User for devise, but it is irrelevant in this case
BankDatum holds information about the user's bank information.

There is a nested form, where the user can edit their profile -> full_name(UserDatum) and iban(BankDatum), hence the accepts_nested_attributes_for.
In the administrate gem I can go to the BankDatum edit form and when I edit it and validations of parent fail I want to show the errors.

Doesn't sound like the rails way, but I have these 3 options for the user: full_name=nil, iban=nil or full_name="Name", iban=nil or full_name="Name", iban="12345"

Here is the script to replicate:

rails new parent_child_errors
cd parent_child_errors
echo 'gem "administrate", "1.0.0.beta1"' >> Gemfile
bundle install
rails g model user_datum full_name:string
rails g model bank_datum iban:string user_datum:references
rake db:migrate
rails generate administrate:install

echo 'class UserDatum < ApplicationRecord
  has_one :bank_datum, dependent: :destroy
  accepts_nested_attributes_for :bank_datum, update_only: true

  # We want to validate the BankDatum, because the user may have changed their full_name
  before_validation do
    if bank_datum
      # Memory touch the bank_datum to make sure
      # its validation will be called by Rails. Go Rails!
      #
      bank_datum.updated_at = Time.now
    end
  end
end' > app/models/user_datum.rb

echo 'class BankDatum < ApplicationRecord
  belongs_to :user_datum

  # If the user wants to input their IBAN, we need their full name
  # If the user doesnt want to input their IBAN, we dont need their full name
  validate :validate_user_datum_fields, if: -> { user_datum.present? && iban.present? }
  validate :validate_bank_data, if: -> { user_datum.present? && iban.present? }


  def validate_user_datum_fields
    if user_datum.full_name.blank?
      user_datum.errors.add(:full_name, :blank)
    elsif user_datum.full_name.size < 2
      user_datum.errors.add(:full_name, :invalid)
    end

    if user_datum.errors.any?
      errors.add(:user_datum, :invalid)
    end
  end

  def validate_bank_data
    # Call an API to validate the IBAN based on the users iban and full_name
    # This is why we need to validate bank_datum every time the user changes their full_name
    nil
  end
end' > app/models/bank_datum.rb

echo 'require "administrate/base_dashboard"

class UserDatumDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    id: Field::Number,
    full_name: Field::String,
    bank_datum: Field::HasOne,
    created_at: Field::DateTime,
    updated_at: Field::DateTime
  }.freeze

  COLLECTION_ATTRIBUTES = %i[
    id
    full_name
    created_at
    updated_at
  ].freeze

  SHOW_PAGE_ATTRIBUTES = %i[
    id
    full_name
    bank_datum
    created_at
    updated_at
  ].freeze

  FORM_ATTRIBUTES = %i[
    full_name
    bank_datum
  ].freeze

  COLLECTION_FILTERS = {}.freeze
end' > app/dashboards/user_datum_dashboard.rb

echo 'require "administrate/base_dashboard"

class BankDatumDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    id: Field::Number,
    iban: Field::String,
    user_datum: Field::BelongsTo,
    created_at: Field::DateTime,
    updated_at: Field::DateTime
  }.freeze

  COLLECTION_ATTRIBUTES = %i[
    id
    iban
    user_datum
    created_at
  ].freeze

  SHOW_PAGE_ATTRIBUTES = %i[
    id
    iban
    user_datum
    created_at
    updated_at
  ].freeze

  FORM_ATTRIBUTES = %i[
    iban
    user_datum
  ].freeze

  COLLECTION_FILTERS = {}.freeze
end' > app/dashboards/bank_datum_dashboard.rb

echo 'UserDatum.create(full_name: "")' > db/seeds.rb

rake db:seed

rails s -p 3002

Now if you go to 'http://localhost:3002/admin/bank_data/new' and try creating a BankDatum with some iban and the UserDatum.
As you see it says: "User datum is invalid", but it would be good to know exactly why it is invalid.

Now if you go to: 'http://localhost:3002/admin/user_data/1/edit' and create a valid situation: enter full_name and iban.
After you have succeeded, go ahead and remove the full_name and save. It shows: "Full name can't be blank" and "Bank datum user datum is invalid", which is ok.

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

No branches or pull requests

1 participant