Hi,
I’m building a LiveView app that has a catalogue of components.
Instead of making a separate function for each return_components_for_vendor_name
I would like to build a more dynamic function where I can pass the component in question.
This function works, but is not dynamic:
# Return Component Vendors that are associated with a display,
# and where we have at least one display.
def component_vendors_for_displays() do
query =
from d in Display,
join: v in assoc(d, :component_vendor),
select: v.id
component_vendor_ids =
Repo.all(query)
|> Enum.uniq()
Enum.map(component_vendor_ids, fn id -> ComponentVendors.get_component_vendor!(id) end)
end
I would love to get something like this to work, but I’m not sure how to accomplish it:
def return_components_for_vendor(component_vendor_id, component) do
query =
from d in component,
join: v in assoc(d, :component_vendor),
select: v.id
component_vendor_ids =
Repo.all(query)
|> Enum.uniq()
Enum.map(component_vendor_ids, fn id -> ComponentVendors.get_component_vendor!(id) end)
end
Here’s my test:
test "find components by component vendor" do
component_vendor = component_vendor_fixture()
camera = camera_fixture(%{component_vendor_id: component_vendor.id})
component = Components.return_components_for_vendor(component_vendor.id, Camera)
assert component == [camera]
end
The test fails here:
** (Protocol.UndefinedError) protocol Ecto.Queryable not implemented for EasySolutions.Components.Camera of type Atom, the given module does not exist. This protocol is implemented for the following type(s): Atom, BitString, Ecto.Query, Ecto.SubQuery, Tuple
code: component = Components.return_components_for_vendor(component_vendor.id, Camera)
stacktrace:
I tried to alias Camera in to the test, but that made no difference.