« Back to channel list

#elixir-lang - 11 June 2019

« Back 1 day Forward 1 day »
[00:55:28] ariedler: has joined #elixir-lang
[00:58:33] Cloudflare: has joined #elixir-lang
[00:59:33] ankhers: I have a nested has_many form using inputs_for. I am using cast_assoc to cast the child data. When I use Repo.insert on my parent type, I'm getting a failure to insert because the children to not have the parent_id field on it. What is the way you are supposed to handle this type of thing?
[01:00:04] Disorganized: has joined #elixir-lang
[01:00:49] ankhers: jnoon2: How are you attempting to build your release? Are you sure you are not currently in the dev environment?
[01:03:04] jnoon2: Ankhers: set "MIX_ENV=prod" && mix do compile, release --env=prod && set "MIX_ENV=" (this is on windows)
[01:04:51] jnoon2: Ankhers: i worked around it for now by putting the right values into the init callback. im not sure if this only happens on custom commands or my ReleaseTasks didnt first load something it should.
[01:06:13] ankhers: I have zero experience with windows and Erlang/Elixir. Sorry. That looks like it should work though.
[01:06:13] ankhers: I have zero experience with windows and Erlang/Elixir. Sorry. That looks like it should work though.
[01:06:40] ankhers: Sorry about that double post. I don't know what I did :(
[01:07:31] jnoon2: ya, the windows thing is not my choice… but has to be deployed that way :( i have some things to try tomorrow and this is a long way from actually getting deployed, so i think ill get it eventually
[01:10:31] ariedler: has joined #elixir-lang
[01:27:22] praveenperera: has joined #elixir-lang
[01:27:22] elixir-logger_: has joined #elixir-lang
[01:29:15] adkron_: has joined #elixir-lang
[01:42:31] tomterl: has joined #elixir-lang
[01:47:43] Disorganized: has joined #elixir-lang
[01:52:52] Exuma: has joined #elixir-lang
[01:53:05] __charly__: has joined #elixir-lang
[02:13:01] adkron_: has joined #elixir-lang
[03:11:51] ariedler: has joined #elixir-lang
[03:23:12] adkron_: has joined #elixir-lang
[03:34:41] wsieroci: has joined #elixir-lang
[03:34:47] Sgeo_: has joined #elixir-lang
[03:55:49] Sgeo__: has joined #elixir-lang
[04:09:18] adkron_: has joined #elixir-lang
[04:21:24] mbuf: has joined #elixir-lang
[04:23:16] mbuf: has left #elixir-lang: ()
[04:47:14] adkron_: has joined #elixir-lang
[05:10:57] drrrty: has joined #elixir-lang
[05:12:47] ariedler: has joined #elixir-lang
[05:27:47] drrty: has joined #elixir-lang
[05:28:03] adkron_: has joined #elixir-lang
[05:36:52] gvaughn: has joined #elixir-lang
[05:40:28] harfangk: has joined #elixir-lang
[05:43:19] ur5us: has joined #elixir-lang
[06:03:37] serafeim: has joined #elixir-lang
[06:03:42] serafeim: good morning
[06:04:02] serafeim: not really related to elixir but is anybody using the electron version of glowing bear ?
[06:04:18] sangoma: has joined #elixir-lang
[06:04:23] Nicd-: you might want to ask on #glowing-bear for support
[06:04:57] serafeim: ha ha ha ok but i just wanted to know about memory consume behavior
[06:05:20] Nicd-: you should ask them
[06:05:24] serafeim: but ok i guess i'll try it myself
[06:06:08] DanielI: it's electron, so i can't imagine it's very lightweight
[06:06:13] DanielI: but yeah, i'd ask in their channel if i were you
[06:06:23] serafeim: Nicd-: the maintainer of the codestats vim plugin actually answered; but the answer was what we expected: it probably isn't working on windows :(
[06:06:30] serafeim: danieli: cool thanks!
[06:06:32] Nicd-: yes I get copies of all the emails
[06:08:01] adkron_: has joined #elixir-lang
[06:08:35] serafeim: it's too bad for me because i more or less use gvim for most of my development... i only use android studio for android and vscode for elixir because i can't fix the elixir-gvim integration
[06:09:58] inerkick: has joined #elixir-lang
[06:16:14] __charly__: has joined #elixir-lang
[06:19:16] tuacker: has joined #elixir-lang
[06:29:12] proteusguy: has joined #elixir-lang
[06:29:54] gde33: has joined #elixir-lang
[06:31:48] voltone: has joined #elixir-lang
[06:47:12] adkron_: has joined #elixir-lang
[06:49:49] gvaughn: has joined #elixir-lang
[07:02:09] squall: has joined #elixir-lang
[07:13:28] ariedler: has joined #elixir-lang
[07:15:13] sevenseacat: has joined #elixir-lang
[07:25:26] ndee: has joined #elixir-lang
[07:31:58] adkron_: has joined #elixir-lang
[07:53:41] jkva: has joined #elixir-lang
[08:04:49] adkron_: has joined #elixir-lang
[08:09:47] jkva: What's Elixir's code style convention regarding `{:ok, value}` and `{:error, value}` return tuples, or returning `value`? When there's a possibility for failure, return a tuple to match on, and if a function always succeeds, return the value? Or return a tuple in any case to generically operate across?
[08:12:56] serafeim: jkva: i think this depends there's no universal convention
[08:13:23] jkva: I wondered whether that was the case. Depends on context, I guess. Cheers serafeim.
[08:14:15] serafeim: most libraries with follow the `{:cond, value}` thing but for your own code i think it's better to just return what's better per situation
[08:16:28] sevenseacat: has joined #elixir-lang
[08:26:22] ur5us: has joined #elixir-lang
[08:26:56] sevenseacat: has joined #elixir-lang
[08:28:11] ur5us: has joined #elixir-lang
[08:30:51] wonko7: has joined #elixir-lang
[08:37:02] Nicd-: jkva: ok-error tuple if function can fail, plain value if not. !-version of function returns plain value or raises error
[08:38:00] gvaughn: has joined #elixir-lang
[08:53:12] flaviodesousa: has joined #elixir-lang
[08:54:35] flaviodesousa: has joined #elixir-lang
[08:55:18] flaviodesousa: has joined #elixir-lang
[08:55:19] jkva: Nicd-: cool - that's my current approach :)
[08:56:08] flaviodesousa: has joined #elixir-lang
[08:57:07] flaviodesousa: has joined #elixir-lang
[08:58:00] flaviodesousa: has joined #elixir-lang
[09:05:45] Sgeo__: has joined #elixir-lang
[09:14:24] ariedler: has joined #elixir-lang
[09:20:05] adkron_: has joined #elixir-lang
[09:35:40] tgrk: has joined #elixir-lang
[09:38:42] Miyu-saki: Is there a way to convert a list of maps into a map of lists?
[09:40:03] Miyu-saki: [%{x => 1, y => 1}, %{x => 2, y => 2}] --> %{1 => [%{y = 1}], 2 => [%{y = 2}]}
[09:40:09] Miyu-saki: I thiinkk the concept is called binning?
[09:40:56] rawtaz: so you want the x to specify the key in the new map?
[09:42:19] nox: You would want sofs but for maps.
[09:42:54] nox: http://erlang.org/doc/man/sofs.html
[09:44:22] Miyu-saki: Seems pretty similar, yeah.
[09:45:08] Miyu-saki: Basically, I wanted to make it so that you can fetch the keys, and then choose a specific key.
[09:45:17] Miyu-saki: Then I realized "wait, aren't that just maps"?
[09:45:22] serafeim: Miyu-saki: can't you do it by hand with `Enum.reduce` ?
[09:45:28] nox: Miyu-saki: Do you even need to get the final map?
[09:45:44] serafeim: or you are asking if there's a way to do it in elixir with builtins ?
[09:45:53] nox: And remove x? Can't you just traverse the original list and return the map with the right key?
[09:46:23] Miyu-saki: nox: Nope. But I feel like this is the most flexible way, albeit a bit more computationally intensive.
[09:46:41] nox: Do you need the flexibility?
[09:46:43] Miyu-saki: Nope being the "need to get the final map?"
[09:47:13] Miyu-saki: Actually, you're right.
[09:47:16] Miyu-saki: Maybe it's better this way.
[09:47:27] Miyu-saki: So I'll instead treat the process as a KV store, instead of returning a map.
[09:48:21] Miyu-saki: This is over a network too, so seems like this is the Better Way TM.
[09:48:43] Miyu-saki: serafeim: Also, I was thinking of bulitins. This is a bit related to Haskell's `traverse`
[09:48:51] Miyu-saki: Or `sequence` IIRC
[09:49:10] Miyu-saki: The types are pretty close.
[09:49:45] micmus: Miyu-saki: `Enum.group_by(list, &Map.get(&1, :x), &Map.delete(&1, :x))`
[09:51:12] Miyu-saki: Ohh. Checking that out, thanks.
[09:51:23] lexmag: has joined #elixir-lang
[09:51:29] Miyu-saki: Though, I feel like treating the process as a KV store is actually the betetr solution.
[09:51:41] Miyu-saki: But I guess I can use this as an internal data?
[09:52:21] Miyu-saki: Like,the access pattern of this is O(log n) vs O(n) I believe?
[09:52:52] Miyu-saki: Actually, it's even better than that, because O(log n) has n as the number of unique keys, while O(n) is all of the data itself.
[09:54:51] Miyu-saki: Thanks for all the help. I'll go do the naive way for now.
[09:57:15] Miyu-saki: Also, Set and HashSet is deprecated?
[10:00:02] micmus: Miyu-saki: yeah, there's MapSet - it's faster and uses less memory than the old implementations (including HashSet), so there's no reason for polymorphism (Set)
[10:00:20] Miyu-saki: Okay. Thanks!
[10:01:12] sillyotter: has joined #elixir-lang
[10:14:55] Miyu-saki: Okay, I'm kinda stupid. This is a problem I've had in Erlang, and I can't believe I'm having this problem again. How do I do this?
[10:15:41] Miyu-saki: I have 2 processes, the 2nd process relies on the 1st process. I want the 2nd process to message the 1st process. Am I required to use `name` here?
[10:16:12] Miyu-saki: An alternative is to make it so that calls accepts 2 PIDs.
[10:16:43] Miyu-saki: Though, I think the proper solution is to make it so that 2nd process accepts the 1st processes's PID on `start`.
[10:16:55] Miyu-saki: Am I correct on this being proper, and if so, how do I do that?
[10:17:24] Nicd-: it sounds like the intuitive thing to me. how to do it, I don't know
[10:18:04] dysfun: i don't quite understand the problem
[10:18:48] dysfun: why can't you just pass self() when you spin up the process that need the other's pid?
[10:19:07] Nicd-: I'm assuming a supervisor boots them both up
[10:20:03] Miyu-saki: Nicd-: Yep yep.
[10:21:50] Miyu-saki: And I don't think dynamic supervisors is the solution here either.
[10:22:04] Miyu-saki: Rather, I think it will just result in complexity.
[10:23:57] dysfun: what do they do?
[10:24:07] dysfun: the two processes
[10:25:13] Miyu-saki: dysfun: One fetches SMS, which is formatted in JSON, and treated with Jason. The second will call the first process to sort it into threads.
[10:26:13] gvaughn: has joined #elixir-lang
[10:26:26] dysfun: so the first process just wants to be registered under a name then
[10:27:30] Miyu-saki: Yep. That's one thing I've been considering.
[10:27:54] dysfun: and the supervisor can be rest_for_all or whatever it is
[10:27:57] Miyu-saki: But I'm quite troubled by the API though.
[10:28:25] Miyu-saki: First.foo(pid), but then Second.foo(pid), calls First.foo(Name)
[10:28:30] voltone: has joined #elixir-lang
[10:28:52] dysfun: Second.foo(name) == Second.foo(pid)
[10:29:12] Miyu-saki: Basically, I'm thinking that it feels weird for me that I can have multiple processes of First, but Second is hardcoded to use only as ingle instance of First.
[10:29:26] Miyu-saki: Though, I'll probalby only be running a single instance of First.
[10:29:40] Miyu-saki: But that means First's API is needlessly generaly.
[10:30:19] Miyu-saki: needlessly general*
[10:30:31] Miyu-saki: Wait, I feel like code will speak better here.
[10:30:59] adkron_: has joined #elixir-lang
[10:32:07] Miyu-saki: dysfun: This.
[10:32:10] Miyu-saki: https://gist.github.com/adrianparvino/3b6952a8871ff9d072057247e842b165
[10:32:40] Miyu-saki: So basically, the first Processes's API allows for multiple processes, so it feels weird for me to make it so that Second harcodes a specific process.
[10:32:56] Miyu-saki: This is probably the most pragmatic way though.
[10:33:41] dysfun: okay, well you need to communicate the pid somehow
[10:34:02] dysfun: if you can't go for a single name, you have to have some sort of registry
[10:35:14] dysfun: how that works is up to you
[10:35:35] Miyu-saki: Taking a look at other OTP toolings right now. Thanks.
[10:35:47] dysfun: there are several 'registry' solutions
[10:35:56] PragTob: has joined #elixir-lang
[10:36:04] dysfun: and sometimes people just roll their own because they don't need the rich featureset
[10:36:43] Miyu-saki: Seems like this is what I need? https://stackoverflow.com/questions/30688877/getting-a-sibling-process-in-elixir
[10:37:31] Miyu-saki: Oh wait. That's the current solution I have, I believe?
[10:37:48] Miyu-saki: Hm, wait, this might actually work.
[10:39:50] Miyu-saki: Okay. What's the scoping of alias/names?
[10:40:27] Miyu-saki: I have this. https://gist.github.com/adrianparvino/c533513e9ccad196760ae2f72b24c230
[10:40:47] Miyu-saki: Oh wait. local alias just means within the node.
[10:40:50] Miyu-saki: So that won't work either.
[10:42:51] voltone: has joined #elixir-lang
[10:43:29] Keksoj[m]: ACTION sent a long message: < https://matrix.org/_matrix/media/v1/download/matrix.org/RRWhhkRBtHkPylfGKaPMDNvL >
[10:44:37] ur5us: has joined #elixir-lang
[10:44:57] Keksoj[m]: Oh wait I found the discussion here : http://stackoverflow.com/a/40408469
[10:44:59] Keksoj[m]: sorry, don't mind me
[10:45:01] Nicd-: Keksoj[m]: I don't think MapSets have a defined order
[10:46:59] Keksoj[m]: yeah so I read
[10:48:43] dysfun: Miyu-saki: names are either cluster-global or node-local
[10:48:53] dysfun: (depending on how you register)
[10:55:08] ariedler: has joined #elixir-lang
[10:56:55] griffinbyatt: has joined #elixir-lang
[11:05:12] dimitarvp: has joined #elixir-lang
[11:15:03] lexmag: has joined #elixir-lang
[11:20:05] Miyu-saki: dysfun: I've decided to just make it fetch/0 or fetch/1, where fetch/1 accepts a hostname atom. I'm hardcoding the name.
[11:21:15] Miyu-saki: I only need at most one fetcher per node anyway.
[11:21:26] Miyu-saki: Which actually means that my hierarchy is sound.
[11:22:33] Miyu-saki: Also, match? is a godsend.
[11:26:03] Miyu-saki: I'm going with this instead.
[11:26:06] Miyu-saki: def fetch(node) do GenServer.call({node, TermuxSmsCli.Fetcher}, :fetch) end
[11:26:29] Miyu-saki: Also, is oneliner, `, do:` also done for functions,or is that bad style?
[11:27:23] serafeim: Miyu-saki: no it's not i've seen it in various places
[11:28:01] serafeim: especially for multiple matchign function headers
[11:28:14] lexmag: has joined #elixir-lang
[11:28:30] Miyu-saki: Hm, thanks.
[11:28:31] drincruz: has joined #elixir-lang
[11:31:19] lexmag_: has joined #elixir-lang
[11:38:15] tnez: has joined #elixir-lang
[11:38:38] adkron_: has joined #elixir-lang
[11:41:31] duane: has joined #elixir-lang
[11:47:29] janlindblom: has joined #elixir-lang
[11:47:40] Miyu-saki: Okay, I'm starting to think I don't understand how distributed Elixir works.
[11:47:53] Miyu-saki: I call this on my desktop
[11:47:56] Miyu-saki: TermuxSmsCli.Thread.threads(:"miyu@192.168.2.8")
[11:48:07] Miyu-saki: And I get ** (FunctionClauseError) no function clause matching in TermuxSmsCli.Fetcher.handle_call/3
[11:48:31] Miyu-saki: But if I call TermuxSmsCli.Thread.threads() on my phone, it works.
[11:48:38] Miyu-saki: Those translate to
[11:48:40] Miyu-saki: GenServer.call(TermuxSmsCli.Thread, :threads)
[11:48:43] Miyu-saki: and GenServer.call({TermuxSmsCli.Fetcher, node}, :threads)
[11:50:07] Miyu-saki: Hm, seems like I'm doing something very wrong here now, since even the first call doesn't work on my phone.
[11:50:16] griffinbyatt: If you're trying to use GenServer calls across a cluster, I think you'll want GenServer.call({:global, name}
[11:50:50] Andrey: has joined #elixir-lang
[11:51:15] Miyu-saki: griffinbyatt: I want it to be local.
[11:51:27] Miyu-saki: Wait. I'll gist the related code.
[11:52:04] Miyu-saki: https://gist.github.com/adrianparvino/d26f4fa3f8d45736e816397d9c8936e7
[11:52:13] Miyu-saki: Is there any glaring issue here
[11:52:14] griffinbyatt: Sure, and my mistake I just realized I misread your code :P
[11:52:22] griffinbyatt: Taking a look
[11:53:01] Miyu-saki: You might have to refresh since I added the error message.
[11:53:58] griffinbyatt: Well, you're trying to use the fetcher with :threads
[11:55:16] Miyu-saki: Yikes, I see it now. Thanks. I copied that from fetcher.ex, since I wanted a pretty consistent API.
[11:56:10] Miyu-saki: iex(miyu@192.168.2.101)11> TermuxSmsCli.Thread.threads(:"miyu@192.168.2.8")
[11:56:11] Miyu-saki: #MapSet<[1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16]>
[11:58:22] fredsir: has joined #elixir-lang
[12:14:35] gvaughn: has joined #elixir-lang
[12:17:50] hypercore: could i get a hand modeling a schema?
[12:17:57] hypercore: having a bit of trouble with this one
[12:33:52] voltone: has joined #elixir-lang
[12:44:49] Sgeo_: has joined #elixir-lang
[12:45:53] adkron_: has joined #elixir-lang
[12:56:08] rogerio: has joined #elixir-lang
[13:06:12] Miyu-saki: Hm, can you recompile through `Node.spawn`?
[13:06:38] Miyu-saki: iex(miyu@192.168.2.101)15> Node.spawn(:"miyu@192.168.2.8", &recompile/0)
[13:06:39] Miyu-saki: #PID<16448.264.0>
[13:06:41] Miyu-saki: Compiling 1 file (.ex)
[13:06:43] Miyu-saki: Seems sooo?
[13:16:21] lexmag: has joined #elixir-lang
[13:17:14] Miyu-saki: Hm, any ncurses-like library that you recommend?
[13:22:58] Miyu-saki: https://github.com/ndreynolds/ratatouille Seems decent.
[13:23:08] Miyu-saki: I need something like Ranger-type IMO.
[13:25:18] Miyu-saki: Oh, MIller Columns.
[13:31:12] lexmag: has joined #elixir-lang
[13:36:26] lexmag: has joined #elixir-lang
[13:45:27] Miyu-saki: Oh damn. This is where the fun begins. I'll finally start programming for my desktop for the UI.
[13:46:10] Miyu-saki: Relevant section in my application.ex. https://gist.github.com/adrianparvino/9f50a02063c3a9c92af546368556d905
[13:49:45] proteusguy: has joined #elixir-lang
[13:56:09] warmwaffles: has joined #elixir-lang
[13:56:51] adkron_: has joined #elixir-lang
[13:58:17] gvaughn: has joined #elixir-lang
[14:00:26] helmut_1: has joined #elixir-lang
[14:02:01] helmut_1: has left #elixir-lang: ()
[14:02:10] adkron_: has joined #elixir-lang
[14:11:23] __charly__: has joined #elixir-lang
[14:12:19] elixir-logger_: has joined #elixir-lang
[14:12:19] praveenperera: has joined #elixir-lang
[14:14:09] Liquid_X: has joined #elixir-lang
[14:14:16] lexmag: has joined #elixir-lang
[14:19:49] flaviodesousa: has joined #elixir-lang
[14:26:38] Liquid_X_: has joined #elixir-lang
[14:34:02] duane: has joined #elixir-lang
[14:51:07] proteusguy: has joined #elixir-lang
[14:56:07] sacredfrog: has joined #elixir-lang
[14:58:29] sacredfrog: has joined #elixir-lang
[14:58:53] greengriminal: has joined #elixir-lang
[15:04:55] aalmazan: has joined #elixir-lang
[15:16:13] tuacker: has joined #elixir-lang
[15:16:42] vaer-k: has joined #elixir-lang
[15:25:05] tamlee: has joined #elixir-lang
[15:26:05] work_: has joined #elixir-lang
[15:27:47] tamlee: has left #elixir-lang: ()
[15:29:52] lexmag: has joined #elixir-lang
[15:32:57] leite: has joined #elixir-lang
[15:37:54] orbyt_: has joined #elixir-lang
[15:45:57] duane: has joined #elixir-lang
[15:51:39] paxis: has joined #elixir-lang
[15:53:15] paxis: has joined #elixir-lang
[15:55:20] jnoon2: has joined #elixir-lang
[16:03:05] swe: has joined #elixir-lang
[16:03:22] swe: Hi again
[16:04:50] Moondhum: has joined #elixir-lang
[16:12:16] adkron_: has joined #elixir-lang
[16:13:51] Miyu-saki: I asked this a while ago, but why doesn't `deps` use the new syntax?
[16:14:05] Miyu-saki: Use the associatve array syntax.
[16:14:38] hypercore: could i get a hand modeling a schema?
[16:15:02] Miyu-saki: It seems to be a list of atoms or tuples with the first element an atom. This screams associative array.
[16:27:49] drincruz: has joined #elixir-lang
[16:27:55] swe_: has joined #elixir-lang
[16:32:07] Miyu-saki: Okay, I just had a stupid idea.
[16:32:22] Miyu-saki: What if we allow `{foo, _} in [...]`
[16:33:45] kamidev[m]: has joined #elixir-lang
[16:37:22] wonko7: has joined #elixir-lang
[16:39:29] micmus: Miyu-saki: it's not consumed as such, though - it's consumed as a collection of dependencies, so a list of tuples works great for that
[16:39:30] ankhers: Miyu-saki: [{:foo, :bar}, {:baz, :quux}] == [foo: :bar, baz: :quux]. It is literally the same thing. I believe the reason the tuple version is more used is because there is no sugar for using a 3 element tuple. And we can use the third element in the tuple to define special options. Like {:distillery, "~> 1.5", runtime: false} or {:phoenix_live_reload, "~> 1.0", only: :dev}, etc.
[16:40:06] Disorganized: has joined #elixir-lang
[16:42:17] proteusguy: has joined #elixir-lang
[16:49:19] Saukk: has joined #elixir-lang
[16:51:27] voltone: has joined #elixir-lang
[16:53:24] Miyu-saki: Ankhers: I sadly am working with strings as the left-hand-side.
[16:53:37] Miyu-saki: Oh wait. We're talking `deps`
[16:53:42] nduro: has joined #elixir-lang
[16:54:12] Miyu-saki: Anyways, valid points, yeah.
[16:54:33] Miyu-saki: I clearly didn't think it through lmao
[16:57:19] proteusguy: has joined #elixir-lang
[17:00:08] drrty: has joined #elixir-lang
[17:17:23] jnoon2: im trying to figure out plugs to serve a static react app for any routes that *dont match* actual routes defined in my phoenix app. so if any path comes in that was not handled, i want to serve the static index.html file. is there a "fallthrough" of some sort where i could implement this?
[17:38:01] adkron_: has joined #elixir-lang
[17:39:53] jfk: has joined #elixir-lang
[17:41:48] jmiven: has joined #elixir-lang
[17:53:26] orbyt_: has joined #elixir-lang
[17:55:16] pera: has joined #elixir-lang
[18:01:14] Miyu-saki: Is there a way to pad Enumerables?
[18:01:22] Miyu-saki: Actually, lists to be exact.
[18:02:29] thurloat: has joined #elixir-lang
[18:02:40] Miyu-saki: I guess I could always do the get the list thingy.
[18:02:45] Miyu-saki: get the length of the list thingy*
[18:09:36] squall: has joined #elixir-lang
[18:15:23] jimobillybob: has joined #elixir-lang
[18:19:12] adkron_: has joined #elixir-lang
[18:19:49] Sgeo__: has joined #elixir-lang
[18:21:27] Disorganized: has joined #elixir-lang
[18:50:30] work_: has joined #elixir-lang
[19:09:21] lexmag: has joined #elixir-lang
[19:15:16] adkron_: has joined #elixir-lang
[19:19:58] jesopo: has joined #elixir-lang
[19:22:13] ankhers: With ex_aws_ses, is there currently a way to add an attachment?
[19:22:23] duane: has joined #elixir-lang
[19:26:53] Disorganized: has joined #elixir-lang
[19:45:44] Miyu-saki: Okay. This probably does not warrant a library function, but I'll give it a try anyways.
[19:46:11] Miyu-saki: Is there a way to concattenate a list of aliases to an alias?
[19:46:24] Miyu-saki: [TermuxSmsCli, Cache] -> TermuxSmsCli.Cache
[19:46:37] micmus: Miyu-saki: Module.safe_concat
[19:46:52] Miyu-saki: Are you kidding me, it actually exists lmao
[19:47:11] benwilson512: Miyu-saki: as far as padding lists goes
[19:47:46] benwilson512: enumerable |> Stream.concat(Stream.repeatedly(fn -> pad_value end)) |> Enum.take(length)
[19:47:52] Miyu-saki: This is actually amazing. I could just put a cache in between, and voila!
[19:48:33] Miyu-saki: Like. The cache and the backend have the same API. I could just switch by switching Aliases in the list.
[19:49:00] Miyu-saki: benwilson512: Also, thanks! I actually needed something like that too.
[19:49:19] Miyu-saki: For a different thing.
[19:50:07] Miyu-saki: benwilson512: https://gist.github.com/adrianparvino/f6adc96b773799e16d042f10ce2f104f
[19:50:20] Miyu-saki: From what I understand, I can just concat it with repeatedly, so that I don't have to do bounds-checking.
[19:50:27] Miyu-saki: Should I or should I not?
[19:50:55] Miyu-saki: Something like
[19:51:25] benwilson512: not really sure what you're doing sorry, why are you checking `index == length threads - 1` ?
[19:51:51] Miyu-saki: enumerable |> Stream.concat(Stream.repeatedly(fn -> last enumerable end)) |> Enum.at(index + 1)
[19:52:01] Miyu-saki: benwilson512: Basically, bounds-checking.
[19:52:27] benwilson512: ah well Enum.at is O(n) so you definitely don't want to let it be unbounded
[19:52:27] Miyu-saki: If index is at length threads - 1, then going above that will mean that I've exceeded the list.
[19:52:44] benwilson512: so padding would be pad since that'll pad infinitely
[19:52:57] benwilson512: can we step back and sort out what you're indices for? I nearly never need to use Enum.at
[19:53:21] Miyu-saki: I guess screenshots will speak more.
[19:53:38] Miyu-saki: Give me a few.
[19:54:15] Miyu-saki: benwilson512: So, take this screenshot for example. https://i.imgur.com/LIuq4FD.png
[19:54:53] Miyu-saki: The left-hand-side updates "asynchronously", so I can't just save the position of the cursor.
[19:55:21] Miyu-saki: Instead, I have to save the content of the cursor, to keep track of my position in the list.
[19:55:33] benwilson512: so, if threads have some kind of identifier, I'd have the threads in a map keyed by the id
[19:55:45] benwilson512: and then refer to the thread by id instead of index
[19:56:26] benwilson512: can you elaborate at what the LHS and RHS of the screenshot is though?
[19:56:29] Miyu-saki: Yep. That's why I'm using that complicated code, because I also have to move between the selectors.
[19:56:50] Miyu-saki: benwilson512: It's an SMS client I'm making, so it's kinda like Milner columns(think Ranger file manager.)
[19:57:51] Miyu-saki: When I receive a new message, then the LHS updates asynchronously.
[19:57:57] Miyu-saki: There *is* something I can do though.
[19:58:14] benwilson512: Right so at least with what you have you can make it simpler by observing that Enum.at returns nil if you exceed the bounds
[19:58:15] Miyu-saki: That is, keep the index, and only do the complicated code when it updates.
[19:58:26] benwilson512: yeah was gonna suggest that too
[19:58:31] Miyu-saki: Wait, crap, you're also right.
[19:58:38] benwilson512: whichever is easier
[19:59:16] Miyu-saki: The cleaner way is keeping the index. OTOH, it also requires keeping track of updates.
[19:59:46] Miyu-saki: Also, thanks. I'll update the code to use the `nil` one for now!
[20:00:43] squall: has joined #elixir-lang
[20:01:23] wsieroci: has joined #elixir-lang
[20:02:53] Miyu-saki: benwilson512: Boom. Much cleaner! https://gist.github.com/adrianparvino/6078c546e7863eccea725ce3135d83c7
[20:03:49] benwilson512: Miyu-saki: perfect!
[20:15:41] PragTob: has joined #elixir-lang
[20:20:48] jakeprem: has joined #elixir-lang
[20:21:13] jeffro: has joined #elixir-lang
[20:31:10] Disorganized: has joined #elixir-lang
[20:34:16] squalloster: has joined #elixir-lang
[20:42:46] Disorganized: has joined #elixir-lang
[20:48:19] averell: has joined #elixir-lang
[21:01:44] icecreamcohen: has joined #elixir-lang
[21:20:04] sebboh: has joined #elixir-lang
[21:26:07] ur5us: has joined #elixir-lang
[21:27:20] pera: has joined #elixir-lang
[21:29:23] icecreamcohen: has joined #elixir-lang
[21:43:50] hypercore: benwilson512, would you mind helping me with modeling my schema?
[21:52:00] __charly__: has joined #elixir-lang
[21:56:09] sebboh: has joined #elixir-lang
[22:12:06] fantasticsid: has joined #elixir-lang
[22:32:29] hypercore: or anyone with good experience with modeling data
[22:41:39] ankhers: What are you trying to do?
[22:48:29] Disorganized: has joined #elixir-lang
[22:50:12] Disorganized: has joined #elixir-lang
[22:55:44] hypercore: Ankhers: basically i have a large number of Products, and each product obviously has its own properties (e.g. tv has [resolution, price], laptop has [weight, resolution, battery size], etc, etc), and i want to basically create templates for each product type
[22:57:07] hypercore: when a seller could click the "add product" button, select "product category = smartphone", and then would be given a form with the inputs defined in the smartphone template
[22:57:14] hypercore: *then a seller
[22:57:29] ankhers: And presumably you would want to be able to dynamically add more product types?
[22:57:53] hypercore: Ankhers: correct, and ideally to update existing templates as well
[22:58:24] ankhers: What happens to the current products if I update an existing template?
[22:58:27] hypercore: (e.g. i might decide i want the "smartphone" template to have a new field called "processor type", or to change the "battery size" field to "battery capacity")
[22:58:55] hypercore: Ankhers: that's something i was hoping you might know :)
[22:59:12] hypercore: ideally the existing products would also be updated
[23:00:20] ankhers: But updated with what information?
[23:01:06] hypercore: Ankhers: yeah ideally
[23:01:22] hypercore: kind of like renaming a database row field
[23:02:08] hypercore: as far as i can tell, i can either create a row for every template field in my "products" table (this seems stupid, because i'd end up with potentially thousands of rows, most of which are never used)
[23:02:29] hypercore: or i can use a json field, with my product templates defined somewhere else
[23:04:09] ankhers: Yeah, I was thinking the templates could be defined in a table. Then you could either embed, or have a "regular" relation for the actual properties.
[23:05:18] hypercore: Ankhers: do you have a table for each product template, or have a single "templates" table that stores all template formats?
[23:05:22] hypercore: *do you mean
[23:06:21] ankhers: Single table for all the templates.
[23:06:55] hypercore: Ankhers: and each row would be a json field?
[23:07:19] hypercore: sorry, i mean the template would be stored in a json field(column)
[23:07:28] ankhers: Are you using postgres?
[23:07:50] ankhers: id | name:text | properties:json (or jsonb)
[23:08:08] ankhers: Plus whatever additional data you need to keep with it.
[23:08:42] ankhers: The properties could look like { "battery size": "string", "foo": "number" }
[23:09:38] ankhers: With the "value" being the input type being displayed on screen.
[23:10:54] hypercore: ok cool, and how do you suggest keeping all product's individual templates synced with this table?
[23:11:29] hypercore: because if i create a product using template-smartphone-v1, and then update the template to v2, my backend code which renders this data might break
[23:12:08] hypercore: e.g. if i have <%= @product.json.batterysize %> for v1, but change to @product.batterycapacity for v2
[23:12:18] hypercore: *@product.json.batterycapacity
[23:16:10] ankhers: I wouldn't look at the template when rendering. I would just render the data that is associated. Maybe you can send an email or any other notification to the users says the template was updated with new fields. Then they can go and edit their product(s) to match the new fields.
[23:16:44] ankhers: Unless there is some acceptable default, you can't really magically update everything.
[23:17:31] hypercore: Ankhers: kind of wanted to be able to render the data in ways other than a key,val table
[23:17:50] ankhers: Like what?
[23:18:05] ankhers: If you have an example, I may be able to help.
[23:18:31] salek_: has joined #elixir-lang
[23:18:49] hypercore: ok, like if the product has a number of videos or images related to it, i might want to render them in a "gallery" section of the page
[23:19:29] hypercore: basically, i wanted each category template to have its own .html.eex file which renders the data in a certain way
[23:19:45] hypercore: maybe this isn't practical though?
[23:21:50] hypercore: or seperate a certain product type information into groups, e.g. for a smartphone template, i could put camera info into one div, cpu/gpu info into another, etc
[23:22:12] pera: has joined #elixir-lang
[23:22:18] ankhers: If you want an actually .eex file, that stops being dynamic and you may as well hardcode things. If you want to stay dynamic, look into whether anyone has built a runtime templating engine. Then let me know, because I need one soon for a project.
[23:22:50] ankhers: I mean, you could still use eex, but I'm not sure how that rates compared to other things.
[23:24:07] ankhers: Maybe mustache or something? I think that is meant to be relatively simple for end users.
[23:24:18] ankhers: I guess it depends on who is creating these templates.
[23:24:25] hypercore: Ankhers: i'm creating the templates
[23:25:12] hypercore: man this ain't easy
[23:25:20] Disorganized: has joined #elixir-lang
[23:25:22] ankhers: Oh, in that case, by all means, you can use the eex format and just call the eex engine to display them. Though, I would still make this part of the template creation. That way you can just change it on the fly without needing to redeploy your application.
[23:25:42] ankhers: But, that is a design choice you can make.
[23:26:21] hypercore: Ankhers: how do i deal with the problem of versioned template's though? (i.e. my .eex product templates might not match older json template designs)
[23:27:13] hypercore: only solution i see to this is updating all existing records to match the new json schema
[23:28:03] ankhers: The easiest, especially if you are using a template engine that has logic (like eex), is you can just do `if @product[:some_field] then ... else ...'.
[23:28:49] ankhers: Either that or make the templates immutable, at least the properties, and always create new ones.
[23:29:56] hypercore: Ankhers: not sure about the if...else.. solution, feel like it could lead to a lot of spaghetti templating (i.e. dozends of if...else.. blocks)
[23:30:15] hypercore: Ankhers: hadn't considered immutable templates actually, interesting
[23:30:46] hypercore: how would you model that? have a "version" column in the template table?
[23:31:03] hypercore: and then each version of a specific template would have its own .eex file?
[23:31:31] hypercore: honestly of all the options so far, this actually sounds do-able
[23:33:28] ankhers: Sounds right.
[23:36:18] hypercore: so to summarize, i create a "product_templates" table, with schema " id:int | product_name:string | template_ver:int | layout:json ", and then i would have a "product_template_id:references:product_template" and "layout:jsonb" field in the Product schema?
[23:38:37] hypercore: and when a seller wants to add a new product (from a particular category, e.g. smartphone), it would generate of field using the "product_template" structure, and then save it into Product.layout, and render it using lib/my_app_web/templates/product_templates/smartphone-ver-1.html.eex?
[23:42:41] ankhers: No. Your "product_templates" table would be id:int | product_name:string | template_ver:int | properties:json | layout:string. Like I said earlier, your properties would look like { "battery_size": "string", "foo": "number" }. This would inform your form which inputs to generate. The layout would be your eex file that tells how to actually render the thing. Your products table would have a reference to the template field, as well as
[23:42:41] ankhers: it's own json with the key:value pairs so it knows how to actually render the product.
[23:43:11] wsieroci: has joined #elixir-lang
[23:43:16] ankhers: Don't save the rendered HTML. Mostly because you want to have the ability to make changes if necessary.
[23:43:20] ankhers: At least, I wouldn't.
[23:44:40] hypercore: Ankhers: just be to clear, you're not talking about storing the html in the database right?
[23:45:00] ankhers: Yes. Do not store the HTML. You just want to store the eex template in the database.
[23:45:30] ankhers: This way you can make changes to the template as needed.
[23:46:09] hypercore: Ankhers: er not the eex template name only? why not just put all my templates into lib/my_app_web/templates/product_templates/{smartphone-ver-1.html.eex, smartphone-ver-2.html.eex, etc}?
[23:46:21] hypercore: or is that what you're saying?
[23:46:31] ankhers: Because then you would need to redeploy your application whenever you add a new product.
[23:46:56] ankhers: Which if you are doing that, you may as well just hardcode the different products into your application and make things easier.
[23:47:33] hypercore: Ankhers: how do you mean hardcode the products?
[23:48:03] ankhers: Have a map or something that describes the different products that you allow.
[23:48:25] hypercore: Ankhers: oh this is not a problem
[23:48:48] ankhers: But why make something mostly dynamic, just to make the templates be hard coded?
[23:49:18] Sgeo_: has joined #elixir-lang
[23:49:50] hypercore: why not just redeploy my app after creating a few new templates though?
[23:50:14] hypercore: e.g. at the end of each day, i could upload the latest templates
[23:50:32] theWhisper_: has joined #elixir-lang
[23:50:40] hypercore: it would still be dynamic in the sense that the templates would change/update
[23:50:58] ankhers: I guess just different ways of thinking. You aren't wrong if you want to do it that way. I would just probably save my eex template to the database.
[23:51:00] hypercore: just not in real time, sellers can only access the updated templates after i've restart the app
[23:51:24] ankhers: But now you need to manage whether or not they can see the templates.
[23:51:58] hypercore: Ankhers: i mean i'm not against it, maybe it's because i grok the "hardcoded" way more easily
[23:52:23] hypercore: if i went with saving the templates in the database, how would i render that in my "product.html.eex" template?
[23:52:42] hypercore: (the general one, not the ones stored in the db)
[23:53:05] hypercore: i.e. the one stored in lib/my_app_web/templates/product/show.html.eex or whatever
[23:53:06] ankhers: I would need to look up how eex works. I haven't worked with it directly.
[23:53:48] hypercore: is it even possible? don't the templates have to be compiled?
[23:54:03] hypercore: maybe not actually
[23:54:28] hypercore: Ankhers: EEx.eval_string("foo <%= bar %>", bar: "baz")
[23:54:48] ankhers: Yeah, that.
[23:54:54] ankhers: I was trying to find a link to that.
[23:55:24] hypercore: so i guess i would call EEx.eval_string(@product.template.layout, @product.template.properties)?
[23:55:36] hypercore: (in product/show.html.eex)
[23:57:30] ankhers: EEx.eval_string(@product.template.layout, properties: @product.properties). You need a keyword list for the second argument. You also want to look at the products properties, not the templates properties.
[23:58:31] hypercore: oh yeah, that makes more sense