7rans

7rans

Update shorthand for Access behavor

I implemented Access behavior for a struct today. Pseudo-code…

defmodule MyStruct do
  defstruct data: %{}
  @behaviour Access
   # ... implementation of Access behavior on `data` ...
end

Then I tried:

  a = %{x: 1, y: 2}
  s = %MyStruct{data: a}
  z = %MyStruct{ s | y: 3 }

And of course it did not work.

Sure would be awesome if it could be made to work somehow though.

Most Liked

cmo

cmo

The way to achieve that is to have two function heads, one that matches on the struct and one that matches on the changeset. You can have the calculate logic in a separate private function and just extract the fields and put the result into whatever structure in each of the function heads.

And where are you going to get the other values for the calculation, if they’re not being passed as args? Passing required arguments to functions is not an antipattern :wink:

LostKobrakai

LostKobrakai

I think one thing is missing from this discussion and that‘s the notion of violating DRY by having ways to calculate the computed value from various sources of data. Instead of trying to avoid repetition by limiting the number of inputs (only struct or only changeset) you can also keep both inputs, but delegate the business logic in question to a shared helper.

def with_computed(%Ecto.Changeset{} = cs) do
  a = get_field(cs, :a)
  b = get_field(cs, :b)
  put_change(cs, :x, compute_x(a, b))
end

def with_computed(%Struct{} = struct) do
  %{struct | x: compute_x(struct.a, struct.b)}
end

defp compute_x(a, b), do: a + b
sodapopcan

sodapopcan

As @D4no0 said, it really sounds like you are trying to create class-like code. The problem with the code you showed us is that it just doubles down on why you think you need access. The real question is: “Why do you need a function that works on both in the first place?” The reason people are questioning you is because there shouldn’t be any reason to need to manually update a key of a schema’s struct, all changes should be done through changesets.

No such thing! Changeset constructors can look however you need to them to. The fact that cast_assoc will automagically look for a changeset/2 function is just a convenience. I won’t name names (@dimitarvp :sweat_smile:) but some people think this in-of-itself is a mistake and the :with option should always be used. Which is just a lot of words to try and re-enforce my point.

sodapopcan

sodapopcan

I used to feel this way! I definitely came around to them. I usually just use put_assoc for tenant-like relationships, or really just anything I don’t want the user to have control over changing, otherwise I just cast the ids directly. And I came to love cast_assoc for many types of nested relationships, but not all! But ya, we don’t have to get into this in this thread :sweat_smile:

D4no0

D4no0

It is absolutely not clear what you want to do, can you show a extensive example that involves ecto changesets?

Or maybe the problem could be reformulated, it is often the case that you will try to do things the way you were used to in other languages.

Where Next?

Popular in Proposals: Ideas Top

MeerKatDev
many times we do stuff like (e.g. test setups, json views in phoenix) aaa = ... bbb = ... ccc = ... %{aaa: aaa, bbb: bbb, ccc: ccc} and...
New
rhcarvalho
Hi all, I would like to gather some feedback before a more intentional proposal to add a new :depth option when specifying a Git depende...
New
rekkice
I’m building an editor integration to evaluate Elixir code in an IEx session. While Code.eval_string/3 allows tracking variable bindings,...
New
kip
Sumary of proposal DateTime.from_iso8601/3 adjusted to: set all numeric fields to the values as parsed (not shifted to UTC), preservi...
New
pdgonzalez872
Hi! There has been some discussion about hiring/jobs on here and I thought about running this by everyone. I wanted to try to help recr...
New
dli
Ecto currently supports some data-modifying WITH statements / CTEs for Postgres: Options: […] :operation - one of :all , :update_all ,...
New
winsalva
Hello all. First of all i’m running this using termux on an android phone. Running mix assets.setup shows this message 06:54:08.450 [de...
New
bartblast
This could resolve to {[a: 1, b: 2]}. Was it ever considered to allow such syntax? Notice this: {:abc, a: 1, b: 2} and this: my_fun(:abc,...
New
sezaru
When writing my code, I always find __MODULE__ very useful to use as alias of that module “inner dependencies”, ex: alias __MODULE__.{Im...
New
dkuku
This is a proposal to make the map key mismatch errors a bit better: Every time I have a typo It’s very challenging for me even when I u...
New

Other popular topics Top

SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement