Not sure how to apply a policy on an attribute of a resource. Keep getting an error.
I have a policy for a resource called user_tokens which is just a way to test a user sign up. User enters phone number and user_tokens will save and send an otp to the mobile number. To avoid abuse, there is a status column which when "locked" should stop sending the SMS. I tried the things as the error suggested but could not overcome the problem yet. Also searched the prior posts but yet to find an answer. Very new to Ash, but hopefully I am not bugging and taking up much of your time in the process of getting past my learning curve. Apologies if I am.
21 Replies
Use the
changing
check for creates
changing(status: [to: :locked])
something like thisThe error message says it further down which I could not post due to size limitation of the post, but it did say this and I did try this. Will do so again so I get the error I got with that.
With this, now it says there is no actor as the error message. But I don't have any actor yet in the system.
At lease one policy has to apply. You don't want the
changing_attributes
check to also be in the conditionThank you. Inserted 1 record now with this policy.
Doing the same action again should do an upsert based as defined in the action. But I am unable to persist an increment of the number of times the SMS was sent.
The sent_count is always shows 1 upon inspection. Inspecting changeset also doesn't show the count incremented.
It did not insert another record in the db, so it must be doing the upsert. But Changeset inspection shows action is still :create
Sorry, if these questions seem too basic. This is my very first attempt at trying to learn Ash
You'll need to use
atomic_update
because on an upsert operation you don't know what is in the database
change atomic_update(:num_sent, expr((^atomic_ref(:num_sent) || 0) + 1))
something like thatI was looking at it but atomic sounded more like to manage concurrency. Would an upsert always have the action in the changeset as :create?
How do we find things like atomic_ref? Couldn’t locate it anywhere in the docs. Is it by looking at code only I can know those or did I miss it anywhere in the docs?
Tried that. A different error. Seems like it won't pick up the required attribute with the "change atomic_update"
Ah, yeah so you need both
The first one should be 1
and all subsequent should be incremented
It isn't incrementing the count even with that. num_sent is always 1.
There is no select statement in the iex output, so I presume there is no way to know what the count is ahead of time to increment it right?
🤔 it should only increment on upsert.
oh
remove
num_sent
from upsert_fields
A bit confused because we do want that field to be updated on update right? Anway, still stuck on 1 which was when it was originally inserted. Not updating after that
🤔 I could swear that I've done exaclty this before. The
num_attempts
in upsert_fields
would set it from the input attribute name
by leaving it out it should still use the atomic update from num_attempts
what does the actual upsert statement look like?
Does it not have the incrementing? Are you sure that you are updating the record etc?Yeah. I see these inserts on the console. Same thing every time I run it
DO UPDATE SET "num_attempts" = ($11::bigint + $12::bigint)::bigint,
that looks like its upserting to me?
oh
its always 1
😆num_sent is the one
always 1
Oh
I just gave you the wrong example I thought it was
num_attempts
Interestingly, it did bump it up to 2 now but running again wouldn't change it. Probably it picked up during macro expansion and wouldn't change it again?
Put the atomic update before the
set_attribute
for num attemptsWow! That did it finally. Now I have to understand what is going on
Why atomic_update here? What is atomic_ref used for and when should we just it versus using the attribute directly? Why did the order of the set_attributes matter?
There should be some information on atomics in the update action guide
Maybe not perfect but it will be a start and maybe we can use this to enhance that guide 🙂
I went through that but I couldn't quite grok the reason why one should be used over the other
I understood the concurrency part and atomic in the function name is aptly named so, but not sure why that would apply in this case
For create actions atomic updates only apply in an upsert case and are used when conflicts exist