I m getting a strange 422 Unprocessable
# avo-2
a
I'm getting a strange 422 Unprocessable Entity error when adding to a has_many association. 🧵
Context: Avo as the primary interface, running with Jumpstart Pro. ActsAsTenant in place with tenancy set to 'Account' Project belongs to Account, and has_many Sites I have the Avo resource for Project show some basic information, and then the sites in a panel at the bottom:
Copy code
panel name: "Project Information" do
    field :name, as: :text
    field :notes, as: :textarea
    field :active, as: :boolean
  end

  panel name: "Project Resources" do
    tabs do
      tab "Sites", description: "Sites" do
        field :sites, as: :has_many
      end
      tab "Workflows", description: "Workflows" do
        field :workflows, as: :has_many
      end
      tab "Datasets", description: "Datasets" do
        field :datasets, as: :has_many
      end
    end
Site resource is straight forward:
Copy code
class SiteResource < Avo::BaseResource
  self.authorization_policy = AccountMemberPolicy

  self.title = :id
  self.includes = []
  # self.search_query = -> do
  #   scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
  # end

  field :id, as: :id
  # Fields generated from the model
  field :name, as: :text
  field :url, as: :text
  field :classification, as: :select, options: Site.classifications_for_select(:titleize)

  # add fields here
end
When I create a site using the 'Create new site' button, and going through the process, it creates the Site as expected, but then after creation, the TurboStream call returns a 422, and the Avo UI throws up two errors: 'You might have missed something. Please check the form.' and 'Validation failed: Project must exist'
Create goes through:
Copy code
web_1       | 16:36:41 web.1    | Started POST "/a/resources/sites?via_relation=project&via_relation_class=Project&via_resource_id=2" for 172.25.0.1 at 2023-07-17 16:36:41 +0000
web_1       | 16:36:41 web.1    | Cannot render console from 172.25.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
web_1       | 16:36:41 web.1    |   User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 2], ["LIMIT", 1]]
web_1       | 16:36:41 web.1    | Processing by Avo::SitesController#create as TURBO_STREAM
web_1       | 16:36:41 web.1    |   Parameters: {"authenticity_token"=>"[FILTERED]", "via_resource_id"=>"2", "via_relation"=>"project", "site"=>{"name"=>"[FILTERED]", "url"=>"https://google.com", "classification"=>"competitor_site"}, "button"=>"", "via_relation_class"=>"Project"}
web_1       | 16:36:41 web.1    |   Account Load (0.6ms)  SELECT "accounts".* FROM "accounts" INNER JOIN "account_users" ON "accounts"."id" = "account_users"."account_id" WHERE "account_users"."user_id" = $1 AND "accounts"."id" = $2 LIMIT $3  [["user_id", 2], ["id", 3], ["LIMIT", 1]]
web_1       | 16:36:41 web.1    |   ↳ app/controllers/concerns/set_current_request_details.rb:36:in `account_from_session'
web_1       | 16:36:41 web.1    |   Pay::Customer Load (0.6ms)  SELECT "pay_customers".* FROM "pay_customers" WHERE "pay_customers"."owner_type" = $1 AND "pay_customers"."default" = $2 AND "pay_customers"."deleted_at" IS NULL AND "pay_customers"."owner_id" = $3  [["owner_type", "Account"], ["default", true], ["owner_id", 3]]
web_1       | 16:36:41 web.1    |   ↳ app/controllers/concerns/set_current_request_details.rb:36:in `account_from_session'
web_1       | 16:36:41 web.1    |   AccountUser Load (0.4ms)  SELECT "account_users".* FROM "account_users" WHERE "account_users"."account_id" = $1  [["account_id", 3]]
web_1       | 16:36:41 web.1    |   ↳ app/controllers/concerns/set_current_request_details.rb:36:in `account_from_session'
web_1       | 16:36:41 web.1    |   User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1  [["id", 2]]
web_1       | 16:36:41 web.1    |   ↳ app/controllers/concerns/set_current_request_details.rb:36:in `account_from_session'
web_1       | 16:36:41 web.1    |
web_1       | 16:36:41 web.1    |   Project Load (0.4ms)  SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = $1 AND "projects"."id" = $2 LIMIT $3  [["account_id", 3], ["id", 2], ["LIMIT", 1]]
web_1       | 16:36:41 web.1    |   TRANSACTION (0.3ms)  BEGIN
web_1       | 16:36:41 web.1    |   Project Load (0.5ms)  SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = $1 AND "projects"."id" = $2 LIMIT $3  [["account_id", 3], ["id", 2], ["LIMIT", 1]]
web_1       | 16:36:41 web.1    |   Site Create (0.7ms)  INSERT INTO "sites" ("name", "url", "project_id", "classification", "raw_data", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["name", "Second Test Site"], ["url", "https://google.com"], ["project_id", 2], ["classification", 1], ["raw_data", nil], ["created_at", "2023-07-17 16:36:41.395792"], ["updated_at", "2023-07-17 16:36:41.395792"]]
web_1       | 16:36:41 web.1    |   TRANSACTION (1.4ms)  COMMIT
l
can you please make a reproduction repo?
it's better if it's not that exact repo
just add the resources that are affected
and you can keep this new repo as a reference for other issues too in the future
a
sure, I'll try
l
thank you!
it helps lower our support requests time
a
for sure!
can I fork Avo and use the dummy app in there?
or better to use the Avo demo app?
l
I think it's best if you don't use the Avo repo as it might get "muddled" with engine-dummy issues
yeah
avodemo should be good
a
ok!
l
I usually start with
rails new
and then hit it with
bin/rails app:template LOCATION='https://avohq.io/app-template'
at the end of these two commands you should have a new rails app with avo installed
a
sounds good
l
we appreciate the help!
a
do you have that in the docs somewhere? That'd be super helpful to have for others.
l
hmm. good point
not really
I'll make a not to add it
thanks!
a
ok, so repro initially didn't work in a bare bones setup. Turns out the culprit is if I try to hide the parent class in SiteResource.
field :project, as: :belongs_to, visible: false
Just showing the field as-is works as-expected.
field :project_id, as: :hidden, default: -> {resource.params[:via_resource_id]}
works, based on the docs and figuring out how to find Project ID. Is there a better way vs digging into resource.params like that?
l
That should be ok
You can also try Avo::App.params[]
This is one of the reasons we ask for reproduction repos. In this process of setting up a repo from scratch we can easily filter out the scenarios where there’s an Avo issue or something app-related
Thanks for going through the paces 🙏
a
for sure. Was easy enough to set up with your oneliner, and have a 'base clean Avo debug app'
then branch to debug individual problems