Access a key from changest

Hey, I got an changeset and need a check if the key is available. If I access a changeset like changeset.asd I get the error not found in changeset. I want to make some action if the key is there. How to check if asd is inside the changeset?
There you can see how a changeset is structured, which should make it obvious why your tried changeset.asd does not work. When you’re there you can look at the various fetch_…|get_… function on the module which should help you do what you want to do.

How to access asd?

You can’t access changeset.asd since the changeset struct linked above doesn’t have that key.

case check if changeset has aasd do
  false ->

How to check if changeset has the key asd?

Since it’s a struct, it can be checked during compilation.

For example,

%Ecto.Changeset{asd: _}

won’t compile.

Do you want to determine if the changeset has a change for that key? There is a changes key in the struct where the changes are stored as well as get_change that will either return what change there is for a key or a default value if there is no change for it.

1 Like

As well as :data field which contains the wrapped value before the changes.

1 Like

asd is optional.

def asd_changeset(struct, params \\ %{}) do
    |> cast(params, [:asd]

I want to check in the controller if asd has a value.

See, you don’t actually need to access :asd on the changeset struct but on the struct wrapped inside the changeset …

You can check if changeset.changes has a value for that key by either checking the :changes map directly or using get_change function.

Or if apply_changes(changeset) has a value for :asd.

If asd has a value I need to check if an other entity in the database uses the same value for asd. asd is a bool. I am building something like an unique constraint in the controller.

But I think gonz is right and get_change will do the job.Thanks gonz.

Then you probably should think about possible race conditions.

If you don’t care about race conditions, check out unsafe_validate_unique/4

I use Repo.transaction with

defp lock_table() do
    Ecto.Adapters.SQL.query!(Repo, "LOCK TABLE asd IN ACCESS EXCLUSIVE MODE;", [])

Will check unsafe_validate, don’t know this one. Thanks

Why not use a database constraint? I don’t think the lock above is a good approach since it significantly limits concurrency. MVCC was developed for a reason …

1 Like

Cool, unsafe_validation seems to do the job :slight_smile: Last 7 years only c# and java for me, so still fighting with elixir. It is frustrating that there is no IDE like Visual Studio or Netbeans for elixir. I use Atom which is a texteditor. A bit frustrating. 2002 I was using console output in ansi c, since there I used an IDE. Now with elixir back to 2002.

Welcome, I guess.

Constraint would be the best, but how to assure with Ecto that only one field (asd) can be true?

Would use in MSSQL or Oracle some stored procedures for this case. But how to add this condition to a migration?

Constraint would be the best, but how to assure with Ecto that only one field (asd) can be true?

A unique index? Depends on the direction that you check, unique among rows, or unique among columns.

Unique would allow one true and one false asd. But i need x false and one true.