TwistingTwists
I have a quiz. and a question.
and relation is.
quiz many_to_many question
question many_to_many quiz
via quiz_question
Now, I want to have an api where I can write Quiz.update_quiz_with_question_ids(existing_quiz,[ qid_1,qid_2,qid_3]) which ends up relating question_ids and quiz_ids.
What I tried:
update :update_quiz_with_question_ids do
accept []
argument :question_ids, {:array, :uuid} do
allow_nil? false
end
change manage_relationship(:questions, :question_ids, type: :direct_control)
end
which leaves with the following error
{:error,
%Ash.Error.Invalid{
errors: [
%Ash.Error.Query.Required{
field: :question_id,
type: :argument,
resource: PyqRatta.Databank.Question,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
],
...
So, I tried a little differently.
update :update_quiz_with_question_ids do
accept []
argument :question_ids, {:array, :uuid} do
allow_nil? false
end
change manage_relationship(:questions, :question_ids,
on_match: :ignore,
on_lookup: :relate,
on_no_match: :relate,
# since we are adding more questions to the quiz.
on_missing: :ignore)
end
and same error persists. Finally, did one more tweak.
defmodule Databank.Changes.QuestionsFromQuestionIds do
@moduledoc """
Fetches questions from database to udpate the relationship from questions to quizzes
"""
use Ash.Resource.Change
alias Databank.Quiz
alias Databank.Question
alias Databank.QuizQuestion
def change(changeset, opts, context) do
quiz_id = Ash.Changeset.get_data(changeset, :id)
qids = Ash.Changeset.get_argument(changeset, :question_ids)
questions =
Enum.reduce(qids, [], fn qid, acc ->
{:ok, question} = Question.read(qid)
acc ++ [question]
end)
Ash.Changeset.force_set_argument(changeset, :question_ids, questions)
end
end
along with
update :update_quiz_with_question_ids do
accept []
argument :question_ids, {:array, :uuid} do
allow_nil? false
end
change Databank.Changes.QuestionsFromQuestionIds
change manage_relationship(:question_ids, :questions, type: :direct_control)
end
the changeset is :
#Ash.Changeset<
api: Databank,
action_type: :update,
action: :update_quiz_with_question_id,
attributes: %{},
relationships: %{
questions: [
{[%{id: "39f41254-f959-4f1d-96d4-30500d96d8d1"}],
[
ignore?: false,
on_missing: :destroy,
on_match: :update,
on_lookup: :ignore,
on_no_match: :create,
eager_validate_with: false,
authorize?: true,
meta: [inputs_was_list?: false, id: :question_id],
type: :direct_control
]}
]
},
arguments: %{question_id: "39f41254-f959-4f1d-96d4-30500d96d8d1"},
errors: [
%Ash.Error.Invalid{
errors: [
%Ash.Error.Query.Required{
field: :question_id,
type: :argument,
resource: Databank.Question,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
],
stacktraces?: true,
changeset: nil,
query: #Ash.Query<
resource: Databank.Quiz,
load: [questions: []],
errors: [
%Ash.Error.Invalid{
errors: [
%Ash.Error.Query.Required{
field: :question_id,
type: :argument,
resource: Databank.Question,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
],
stacktraces?: true,
changeset: nil,
query: #Ash.Query<
resource: Databank.Question,
filter: #Ash.Filter<id == nil>,
errors: [
%Ash.Error.Query.Required{
field: :question_id,
type: :argument,
resource: Databank.Question,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
],
select: [:id, :question_text, :question_image, :type,
:correct_answer_text, :correct_answer_image,
:explanation_text, :explanation_image, :short_description,
:long_description, :year, :tags, :created_at, :updated_at]
>,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
},
%Ash.Error.Query.Required{
field: :question_id,
type: :argument,
resource: Databank.Question,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
}
]
>,
error_context: [nil],
vars: [],
path: [],
stacktrace: #Stacktrace<>,
class: :invalid
},
...
The reasoning behind this is : if manage_relationship can alter the fields via given relationship key. But that doesn’t appear to be the case for many to many
TL;DR
create an Api where
relation is.
quiz many_to_many question
question many_to_many quiz
via quiz_question
Quiz.update_quiz_with_question_ids(existing_quiz,[ qid_1,qid_2,qid_3]) which ends up relating question_ids and quiz_ids.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
zachdaniel
type: :append_and_remove.:direct_controlwill attempt to create, destroy and update questions to make the relationship look exactly like the provided values. So any given new value that is missing has to be enough input to call the corresponding create action.type: :append_and_removewill attempt to relate and unrelate existing questions.TwistingTwists
this doesn’t work either. same error. I can put a small demo repo, if you’d like
zachdaniel
Ah, so the required argument bit is because arguments are required to be provided when the changeset is built. If you have an argument with
allow_nil? false, you can’t set it in a change to avoid the error.zachdaniel
You should be able to do
and then
Ash.Changeset.for_....(%{question_ids: [....]})If you just want them to add, and not remove ones they didn’t supply, then use
type: :appendTwistingTwists
https://github.com/TwistingTwists/pyq_ratta/blob/d6b0b60e90df721f913c96bd6c9c79ea9062aba1/test/pyq_ratta/quiz_test.exs#L30
try running this test via
mix test test/pyq_ratta/quiz_test.exs:30on branchfeat/upload_questionsTwistingTwists
That makes sense.
https://github.com/TwistingTwists/pyq_ratta/blob/f6178f75322b4c544ce3678d0d41fabda7f15f1d/lib/pyq_ratta/databank/resources/quiz.ex#L82
However, even after trying that, tests fail. I suspect it is something else. :\
branch name is
feat/upload_questionszachdaniel
I may have time to look tomorrow. Are you getting an error with that setup? Or how are your tests failing?
TwistingTwists
errors are:
error as Github Gist
just realised I had not pushed migrations. pushed now.
zachdaniel
Weird I don’t see how you could be getting a required argument called
:question_idwhen you don’t even have an argument anywhere in the question resource called:question_id.zachdaniel
Ah, never mind, you do
This is the issue:
Your primary read action should not have required arguments. If it does, anything that tries to use it (like
manage_relationshipwon’t know what to supply as the argument value.