Hi, all! Suppose I have 2 schemas mapping 2 similar external API responses:
defmodule Foo do
use Ecto.Schema
embedded_schema do
belongs_to :common_field_1, CommonField
field :common_field_2, :integer
field :common_field_3, :string
field :foo_specific_field, :integer
end
def changeset(params) do
%Foo{}
|> cast(...)
|> validate_common_fields()
|> validate_foo_specific_fields()
end
def validate_common_fields(%Ecto.Changeset{} = changeset) do
# Uses only common fields
end
def validate_foo_specific_fields(%Ecto.Changeset{} = changeset) do
# Uses common and specific fields
end
end
defmodule Bar do
use Ecto.Schema
embedded_schema do
belongs_to :common_field_1, CommonField
field :common_field_2, :integer
field :common_field_3, :string
field :bar_specific_field1, :integer
field :bar_specific_field2, :string
end
def changeset(params) do
%Bar{}
|> cast(...)
|> validate_common_fields()
|> validate_bar_specific_fields()
end
def validate_common_fields(%Ecto.Changeset{} = changeset) do
# Uses only common fields
end
def validate_bar_specific_fields(%Ecto.Changeset{} = changeset) do
# Uses common and specific fields
end
end
What is the best way to avoid dup code in that case? I can move common validations in another module. But how to deal with common fields in schema definitions?
I would expect this to be a case of driving DRYness to far. Those API resonses are currently similar, but will they stay that way in the future? Will changes happen in both responses at the same time? Having common validation is a nice option to prevent having to fix business rules in two places, but the schema is just a static representation without many moving parts.
@NobbZ@LostKobrakai Thank both of you, guys. I understand your concerns on overDRYing schema definitions. In our case we have not 2 but 5 such schemas. Perhaps, we will consider requesting external API refactoring.