Hello everyone,
I’m trying to take data from one structure and save it on a similar structure when creating a record through function.
My data is saved fine as long as I don’t send data from embed schema answers.Can someone please advise me how to properly send data from embed schema please? I thought I could work with answers as another atom, but I can’t.
I have this error: expected changeset data to be a Elixir.MyApp.AssessmentAppPipelines.AssessmentAppPipeline.AssessmentAnswer struct, got: %MyApp.AssessmentPipelines.AssessmentPipeline.AssessmentAnswer{id: "05bcf97a-84ed-478f-a74a-b6da9aa2a28f", title: "T1", score: 2, answ_id: nil, delete: nil}
Structure is:
Schema_A has_many Schema_B embeds_many Embed_Schema_C
create →
Schema_D has_many Schema_E embeds_many Embed_Schema_F
Function:
def create_assessment_app_pipeline_from_assessment_pipeline(
%AssessmentPipeline{} = assessment_pipeline,
attrs \\ %{}
) do
attrs
|> Map.merge(%{
"assessment_pipeline_id" => assessment_pipeline.id,
"questions" =>
Enum.map(assessment_pipeline.assessment_questions, fn m ->
m
|> Map.from_struct()
|> Map.take([:question, :description, :category, :multiple_choice, :assessment_answers])
end),
.
.
.
"count_of_questions" => length(assessment_pipeline.assessment_questions)
})
|> create_assessment_app_pipeline()
end
def create_assessment_app_pipeline(attrs \\ %{}) do
%AssessmentAppPipeline{}
|> AssessmentAppPipeline.changeset(attrs)
|> Repo.insert()
end
I have these schemas:
Pipeline
schema "assessment_app_pipelines" do
field :progress, :integer, default: 0
field :status, AssessmentAppPipeline.Status, default: :draft
field :submitted_at, :naive_datetime
field :evaluation, :integer, default: 0
field :count_of_evaluations, :integer, default: 0
field :count_of_questions, :integer, default: 0
.
.
.
timestamps()
belongs_to :company, Company
belongs_to :assessment_pipeline, AssessmentPipeline
has_many :questions, AssessmentAppPipeline.Question
.
.
.
end
def changeset(assessment_app_pipeline, attrs) do
assessment_app_pipeline
|> cast(attrs, [
:company_id,
:assessment_pipeline_id,
:count_of_questions
])
|> put_assoc(:questions, Map.get(attrs, "questions"))
|> validate_required([
:questions,
:company_id,
:assessment_pipeline_id
])
|> unique_constraint(:company_id,
name: :assessment_app_pipelines_company_id_assessment_pipeline_id_index
)
end
Question
schema "assessment_app_pipeline_questions" do
field :question, :string
field :description, :string
field :category, :string
field :multiple_choice, :boolean, default: false
embeds_many :assessment_answers, MyApp.AssessmentAppPipelines.AssessmentAppPipeline.AssessmentAnswer, on_replace: :delete
belongs_to :assessment_app_pipeline, MyApp.AssessmentAppPipelines.AssessmentAppPipeline,
type: :binary_id
belongs_to :updated_by, MyApp.Users.User, type: :binary_id
timestamps()
end
def changeset(question, attrs) do
question
|> cast(attrs, [
:question,
:description,
:category,
:answer,
:updated_by_id,
:multiple_choice
])
|> cast_embed(:assessment_answers, with: &MyApp.AssessmentAppPipelines.AssessmentAppPipeline.AssessmentAnswer.changeset/2, required: true)
|> validate_required([
.
.
.
])
end
Embed schema
embedded_schema do
field :title, :string
field :score, :integer
field :selected, :boolean
end
def changeset(assessment_answer, attrs) do
assessment_answer
|> cast(attrs, [:title, :score, :selected])
|> validate_required([:title, :score])
end
If you need more information I will add.
Thanks for any help!