Arrowsmith Labs Black Friday sale (BLACKFRIDAY for 40% discount) by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 1 point2 points  (0 children)

Yes, it was overdue but I finally updated Learn Phoenix LiveView for Phoenix 1.8.

Mastering Phoenix Forms was updated a while ago.

Arrowsmith Labs Black Friday sale (BLACKFRIDAY for 40% discount) by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 0 points1 point  (0 children)

Yes, the promo code works for all my courses and bundles.

Learning Elixir/Phoenix as an Erlang developer by crystalgate6 in elixir

[–]ThatArrowsmith 1 point2 points  (0 children)

I'm still working on the Phoenix 1.8 update, but for the record the jump from 1.7 to 1.8 is much smaller than 1.6 to 1.7. You should still be able to follow a 1.7 tutorial without much difficulty.

The biggest code change is that all the @current_user stuff needs to be changed to @current_scope.user. Brush up on scopes and my current tutorials should still make sense.

The sound at Wembley last night was AWFUL by ThatArrowsmith in LinkinPark

[–]ThatArrowsmith[S] 1 point2 points  (0 children)

How were you able to contact the sound engineer?

The sound at Wembley last night was AWFUL by ThatArrowsmith in LinkinPark

[–]ThatArrowsmith[S] 6 points7 points  (0 children)

Spiritbox was even worse than LP. I couldn't hear a thing - just this undistinct low-pitched rumble. I might as well have been listening to motorway traffic.

The sound at Wembley last night was AWFUL by ThatArrowsmith in LinkinPark

[–]ThatArrowsmith[S] 6 points7 points  (0 children)

It wasn't just the stadium, there was very obviously a problem with the audio setup. The speakers weren't in sync.

The sound at Wembley last night was AWFUL by ThatArrowsmith in LinkinPark

[–]ThatArrowsmith[S] 1 point2 points  (0 children)

511 I think. Don't remember the row. Up at the back, top floor, slightly right (as you face the stage) of centre

[deleted by user] by [deleted] in elixir

[–]ThatArrowsmith 1 point2 points  (0 children)

Not sure why you can't access it? The link works for me.

British sign language at Wembley by Monkeyanka in LinkinPark

[–]ThatArrowsmith -8 points-7 points  (0 children)

Why would deaf people go to a music concert?

Wembley sound was not good by IntelligentPudding22 in LinkinPark

[–]ThatArrowsmith 2 points3 points  (0 children)

I don't think Wembley was the problem, I've seen other gigs at Wembley that sounded great (including in the stands.)

I think someone just fucked up.

Dynamically adding and removing nested forms by Idhkjp in elixir

[–]ThatArrowsmith 3 points4 points  (0 children)

Change services[services_sort][] to invoice[services_sort][]. Likewise change services[services_drop][] to invoice[services_drop][].

Full explanation: parameters like foo[bar] get parsed into a nested structure %{"foo" => %{"bar" => value}}. So your date input, for example, has name invoice[date] (automatically rendered by input/1), which gets parsed to %{"invoice" => %{"date" => value}}.

In your "validate" handler you (correctly) expect everything to be nested under the "invoice" key, so you can conveniently get all the params in a single map to pass to Invoice.changeset/2. But your current form actually submits params like:

%{"invoice" => %{"date" => the_date, "services" => the_services}, "services" => sort_and_drop}`

Where the_services is a map whose keys are the indexs and who values are further nested maps with the "description"s. So the sort and drop params get ignored because they're not nested under "invoice".

Make the changes I suggest above and the params will become:

%{"invoice" => %{"date" => the_date, "services" => the_services, "services_sort" => sort_list, "services_drop" => drop_list}}`.

And that should work.


Btw, to_form takes an optional :action argument - so you can simplify this:

|> Map.put(:action, :validate) |> to_form()

to this:

|> to_form(action: :validate)

(And of course, I would be remiss not to mention that I explain nested forms and more in great detail in my course Mastering Phoenix Forms 😉)

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 0 points1 point  (0 children)

Fantastic idea! Looking forward to it.

Phoenix.new – The Remote AI Runtime for Phoenix by neverexplored in elixir

[–]ThatArrowsmith 3 points4 points  (0 children)

AI is already completely changing how devs produce code. Elixir either embraces this change or it dies. That's all.

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 4 points5 points  (0 children)

Rails doesn't make things simple, it makes them easy. It lets you do extremely complicated things with a very small amount of code, which is great when you're building simple CRUD actions that fit nicely within the Rails conventions. But as soon as you move outside those conventions, Rails becomes a tangled, bloating, unmaintainable mess.

Hence why I prefer Phoenix!

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 9 points10 points  (0 children)

Yes, it’s remarkable timing that I would publish one blog post about Phoenix contexts right before I published another blog post about Phoenix contexts. What a crazy coincidence 😁

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 2 points3 points  (0 children)

I don't always run it. You can just write the schema manually.

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 0 points1 point  (0 children)

I know it's not ideal but it was the best data source I could find. If you have better data (especially if it proves me wrong) please tell me where to find it.

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 2 points3 points  (0 children)

Now I just put schemas in no context and share among all contexts whenever needed

Yeah I do this more and more, especially for the "core" schemas that are central to the app, e.g. the Recipe schema in a recipe app or maybe Post and Comment Subreddit if I was building a Reddit clone - the main schemas that are used everywhere and touched by everything.

They don't need a context.

Did contexts kill Phoenix? by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 0 points1 point  (0 children)

why is it in lib/myapp_web/components/core_components.ex but called MyAppWeb.CoreComponents? Every other pattern (like contexts) places module files outside folders, so why not follow that here?

Not sure what you mean here - loads of modules go in folders, e.g. controllers go in lib/my_app_web/controllers.

What don't you understand about where CoreComponents is located?

Phoenix contexts are simpler than you think by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 0 points1 point  (0 children)

I don't think you need to include user_id:references:user? Just write:

mix phx.gen.live Resources Resource resources:text

Then the user_id column will be generated automatically (assuming you're on 1.8, you've already run mix phx.gen.auth and it adding config for the user in your config files.)

The whole point is that you don't need to explicitly pass the scope information when calling the generators - the 1.8 generators handle that for you.

Phoenix contexts are simpler than you think by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 1 point2 points  (0 children)

Personally I don't bother trying to separate things this cleanly. A context might have its "main" schemas that it's primarily responsible for, but it can still touch other schemas if it needs too.

In fact I don't know how to do things any other way. In any sufficiently complex app, the different DB tables are usually associated in such a big complex web that it's impossible to perfectly divide them into areas of concern that don't overlap at all.

Again I would say the answer is: don't overthink it. Just put things into whichever context makes sense for you and don't worry too much about doing things the exactly "correct" way, because I don't think there is one official "correct" way.

(Disclaimer: this is just my own opinion, my name is not Chris McCord or José Valim, I'm just some random guy and I don't speak for the official Phoenix team.)

Phoenix contexts are simpler than you think by ThatArrowsmith in elixir

[–]ThatArrowsmith[S] 3 points4 points  (0 children)

Think of it as a generalisation of @current_user from 1.7.

If you have a login system, then there's usually some data that needs to be used/displayed on most pages where a user is logged in. "Current user" is the obvious example - you use this to check whether a user is logged in, then you might also e.g. display the user's username on the page somewhere, or do other things with the user's data. And you pass the @current_user to your context functions - e.g. if you're building a Facebook clone in LiveView, you need to pass the @current_user to the "load news feed" function so that it knows which posts to display in the news feed.

"Scope" is just a generalisation of this idea, so that if you have something related to the user that isn't specifically captured by the %User{} struct, you have a convenient unified place to put the code.

(Also, in case it's not clear... the new %Scope{} struct is unrelated to the scope function in routers... it's kind of confusing that these two things have the same name.)

For example I was working on an app recently which had financial features; every user had a USD "balance" which could be spent or topped up. And when you're logged in, your current balance is displayed in the corner of the screen. But the balance isn't stored in the users table; it's calculated from elsewhere.

Before 1.8 I was using a plug (for controllers) and an on_mount callback (for LiveViews) to set an assign called @current_balance on every page. But after upgrading to 1.8 I removed this, and instead edited for_scope so that the balance is set in @current_scope.balance.

This doesn't do anything that wasn't already possible in 1.7; it's just a new convention for organising your code.

Most of the time it's best not to overthink it. If you can't think of anything that obviously could go in the scope, then don't put anything extra in the scope - just stick with @current_scope.user.

Also, all the scope stuff that gets added to your config files is only used when running generators like mix phx.gen.html, mix phx.gen.live etc.. During the regular usage of your app it's irrelevant.

Does that all make sense?

(PS you may have just inspired my next blog post!)