backpex
backpex copied to clipboard
HasManyThrough to Resource with a BelongsTo Fails
Describe the bug Trying to create a HasManyThrough field to a resource that has a BelongsTo and get an error:
no match of right hand side value: nil
lib/backpex/fields/belongs_to.ex
@impl Phoenix.LiveComponent
def update(assigns, socket) do
%{schema: schema, name: name, field: field} = assigns
%{queryable: queryable, owner_key: owner_key} = schema.__schema__(:association, name)
display_field = display_field(field)
display_field_form = display_field_form(field, display_field)
The assigns is getting the schema for the Root resource and not for the "Through" resource.
Example Schemas and Config
defmodule MyApp.Report do
use Ecto.Schema
alias MyApp.ReportColumn
alias MyApp.ReportColumnCalculation
alias MyApp.ReportConstraint
schema "reports" do
field :key, :string
field :title, :string
field :description, :string
has_many :report_columns, ReportColumn
has_many :columns, through: [:report_columns, :column]
timestamps()
end
end
defmodule MyApp.ReportColumn do
use Ecto.Schema
alias MyApp.Column
alias MyApp.Report
schema "report_columns" do
belongs_to :report, Report
belongs_to :column, Column
field :sort, :integer
field :visible, :boolean, default: true
timestamps()
end
end
defmodule MyApp.Column do
use Ecto.Schema
alias MyApp.ColumnConstraint
alias MyApp.Operation
alias MyApp.QueryColumn
alias MyApp.ReportColumn
schema "columns" do
field :title, :string
field :abbreviation, :string
field :description, :string
field :format, Ecto.Enum,
values: [
regular: "regular",
text: "text",
float: "float",
integer: "integer",
percent: "percent"
]
belongs_to :operation, Operation
timestamps()
end
end
defmodule MyApp.Operation do
use Ecto.Schema
schema "operations" do
field :key, :string
timestamps()
end
end
defmodule MyAppWeb.Admin.ReportLive do
use Backpex.LiveResource,
#...
@impl Backpex.LiveResource
def fields do
[
title: %{
module: Backpex.Fields.Text,
label: "Title"
},
description: %{
module: Backpex.Fields.Text,
label: "Description"
},
columns: %{
module: Backpex.Fields.HasManyThrough,
label: "Columns",
display_field: :title,
live_resource: MyAop.Admin.ColumnLive,
except: [:index],
sort_by: [:sort],
pivot_fields: [
sort: %{
module: Backpex.Fields.Number,
label: "Sort"
},
visible: %{
module: Backpex.Fields.Boolean,
label: "Visible"
}
]
}
]
end
end
defmodule MyAppWeb.Admin.ColumnLive do
use Backpex.LiveResource,
#...
@impl Backpex.LiveResource
def fields do
[
output_key: %{
module: Backpex.Fields.Text,
label: "Key"
},
title: %{
module: Backpex.Fields.Text,
label: "Title"
},
abbreviation: %{
module: Backpex.Fields.Text,
label: "Abbreviation"
},
description: %{
module: Backpex.Fields.Text,
label: "Description"
},
operation: %{
module: Backpex.Fields.BelongsTo,
label: "Operation",
display_field: :key
},
format: %{
module: Backpex.Fields.Text,
label: "Format"
}
]
end
end
Expected behavior I'd exepect this case to work and display the values from the "Through" resource.