<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="36744" data-post-id="36744">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="PJextra" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  PJextra
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>For newbies everything can be a barrier.<br>
Especially if you’re a programming newbie too. That was my case and I remember my first days with Phoenix/Elixir when after reading some guides and documentation I tried to start my project. I did know HTML and CSS and some jQuery but I still remember that I just didn’t know if I should put my code on an .exs or an .ex file. And exactly on which file.<br>
The good thing was that I asked for help and as much as my questions were strange, I always got the help that I needed. Very fast.<br>
Then, every here and then I felt the same with other issues. I looked to other languages and frameworks, experimented a little bit with them and as long as I could copy some code I was good. When I had to think for myself, then…I always got back to Elixir/Phoenix because not only I always got the help I needed as I realised more and more that the mindset behind it was really powerful. I always realised that they were more or at least as correct as on others languages an frameworks.<br>
And so on.<br>
These last months, with some simple apps running in production I, again, though: contexts…I’ll need to refactor my code AND MY MIND. I delayed it, but then when I started refactoring the code, not only I realised that CONTEXTS ARE BETTER than what existed but I ALSO LEARNED A FEW MORE things along the way.<br>
These are the efforts that make us better. That force us to grow. Nobody likes to change when they don’t feel in the mood to change. I don’t. I try to delay it and avoid it. I go looking for alternatives that are less pailful.<br>
Only to realise that to get to the top and really understand every line of my code I need to go through this.<br>
Of course I have some colleagues that keep copying and pasting code that they find googling. They produce code, not software. They can’t change that code after 1 year.<br>
I hate to comment my code. But I love it after some months.<br>
In the end a newbie must decide: are contexts a barrier too high to be a good software developer?  If yes, then copy paste code is what you’ll get. No pain but not really a lot of gain.<br>
If you don’t believe, (as a newbie) please try to do the same solid, fast, scalable and fault-tolerant web app using Go. I tried 3 times and gave up. Try do it using Rust. I tried 2 times and gave up. Try do it using Node/Javascript. I tried, I though I did only to realise that they were not maintainable nor scalable…Try do it with Swift and you’ll realise that Windows is not an option.<br>
Of course there are other languages and frameworks. But I’m focusing only on relatively new languages. And only as a newbie that is not a programming PRO. Because I believe that  really pros will find problems either way and they are used to solve them.</p>
<p>PS: It’s very important to trust the ones that were able to continuously evolve Elixir/Phoenix in the right direction. Especially when we don’t have a better idea to solve the issues that were visible and are being solved using contexts. So for me, contexts WILL IMPROVE as everything else and if in a few years we’ll have to change…,then will do!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36744" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/82">Post #81</a>
	                </div>
	            </div>
              <div id="likers-container-36744" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36744"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #81"></div>
  </section>
</div>
    <div class="postbit" id="36760" data-post-id="36760">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nerdyworm" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nerdyworm/120/359_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nerdyworm
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I had some time to go through <a href="https://github.com/hexpm/hexpm" class="inline-onebox" rel="noopener nofollow ugc">GitHub - hexpm/hexpm: API server and website for Hex · GitHub</a> as it was mentioned as a good resource to learn how the authors used contexts in practice.</p>
<p>What I found were a bunch of namespaced schemas (let’s be honest, they are models with validations, persistence, and queries), not the proposed contexts that the generators are producing.</p>
<p>Here is my take away from this:</p>
<p>Namespaced Schemas which define their public api == clean, understandable, seems to works well and blessed by the core team as a solid example.</p>
<p>Contexts as proposed == MIA</p>
<p>I’ll say it again, it would be splendid to see real examples of how Contexts actually shake out from people that have been thinking about them for a while.  Nothing would benefit this conversation more than a large hunk of code that we can all look at and judge.</p>
<p>Cheers,<br>
Benjamin</p>
<p><em>P.S.  Apologies if my writing comes across anything but friendly.  Most of my terrible jokes are terrible <img src="https://forum.elixirforum.com/images/emoji/apple/stuck_out_tongue.png?v=15" title=":stuck_out_tongue:" class="emoji" alt=":stuck_out_tongue:" loading="lazy" width="20" height="20"> However I think that the snarkiness that is in this thread gave a lot of the frustrated folks a chance to let out how they really felt.  Like they say, you’ve never really used something until you have used it in anger <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></em></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36760" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/83">Post #82</a>
	                </div>
	            </div>
              <div id="likers-container-36760" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36760"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #82"></div>
  </section>
</div>
    <div class="postbit" id="36769" data-post-id="36769">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chrismccord" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrismccord/120/24233_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chrismccord
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Phoenix</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My ElixirConfEU keynote is up on youtube and the first part of the talk addresses some of the points here – confusions around contexts, feedback we’ve gotten, why we named it “contexts”, etc. It might be worth watching for some added… context <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<div class="youtube-onebox lazy-video-container" data-video-id="pfFpIjFOL-I" data-video-title="Chris McCord | Keynote: Phoenix - Gauging Progress" data-video-start-time="" data-provider-name="youtube">
  <a href="https://www.youtube.com/watch?v=pfFpIjFOL-I" target="_blank" class="video-thumbnail" rel="noopener nofollow">
    <img class="youtube-thumbnail" src="https://img.youtube.com/vi/pfFpIjFOL-I/maxresdefault.jpg" title="Chris McCord | Keynote: Phoenix - Gauging Progress" width="690" height="388">
  </a>
</div>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36769" data-batch-url="/posts/batch_likers">
                        10
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/84">Post #83</a>
	                </div>
	            </div>
              <div id="likers-container-36769" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36769"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #83"></div>
  </section>
</div>
    <div class="postbit" id="36821" data-post-id="36821">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ericmj" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ericmj/120/25920_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ericmj
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Elixir Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="nerdyworm" data-post="83" data-topic="5929">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nerdyworm/48/359_2.png" class="avatar"> nerdyworm:</div>
<blockquote>
<p>I had some time to go through <a href="https://github.com/hexpm/hexpm" class="inline-onebox" rel="noopener nofollow ugc">GitHub - hexpm/hexpm: API server and website for Hex · GitHub</a> as it was mentioned as a good resource to learn how the authors used contexts in practice.</p>
</blockquote>
</aside>
<p>One important note here is that the way hexpm is using contexts may not be what the phoenix team envisioned and although we have been working on separating our concerns into contexts there are some places they leak through because it’s an ongoing effort. Hexpm started out without contexts and it worked just fine for multiple years but as the project grew we felt we needed to split some parts apart and since contexts were introduced around the same time we felt that was a good way of doing it. We are also not following contexts religiously, for example we don’t use umbrellas, this is also fine.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36821" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/85">Post #84</a>
	                </div>
	            </div>
              <div id="likers-container-36821" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36821"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #84"></div>
  </section>
</div>
    <div class="postbit" id="36868" data-post-id="36868">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nicbet" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nicbet/120/28763_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nicbet
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sync08" data-post="10" data-topic="5929">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/s/ed655f/48.png" class="avatar"> sync08:</div>
<blockquote>
<p>because I love generators (why do people keep on dismissing them as only learning tools <img src="https://forum.elixirforum.com/images/emoji/apple/confused.png?v=15" title=":confused:" class="emoji" alt=":confused:" loading="lazy" width="20" height="20">) and it provides the maximum amount of separation for minimum effort.</p>
</blockquote>
</aside>
<p>Exactly!! How annoying it’s is to write the same boiler plate over and over again. One of the reasons I like rails is that I can stub out the boilerplate with a generator, delete what I don’t need and move fast from there. If anything, Phoenix needs more and more powerful generators.</p>
<p>Blog posts, articles, documentation and step by step guides are fantastic learning tools and I would argue more effective then machine generated files that you have no idea how they came to be. It’s something that’s been bugging me from the beginning, this notion of generators as learning tools as opposed to productivity tools.</p>
<p>That said, personally I do like the move away from models to bounded contexts, the more time I spend with 1.3.0. The trick as others have mentioned is to not read too much design patterns into it - it’s just files and directories, but they encourage better separation and better separation of concerns is always a good thing in software.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36868" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/88">Post #87</a>
	                </div>
	            </div>
              <div id="likers-container-36868" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36868"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #87"></div>
  </section>
</div>
    <div class="postbit" id="36877" data-post-id="36877">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think 'Context’s are a good idea, just the name is weird (I’ll watch the video when I can ^.^), but the way I do it is shaped by decades of Erlang, C++, Python, and Java, with lots of other languages sprinkled in, so my Elixir projects may be a little different in style.  Basically here is what I do:</p>
<ul>
<li>
<p><strong>Web:</strong>  Is strictly for front-end things like controllers, channels, commanders, routing, and views/templates.  Everything is kept as minimal as possible just calling out to somewhere else to get data (growingly becoming <code>Absinthe.run</code> in a lot of places…) and send it back out.</p>
</li>
<li>
<p><strong>Models:</strong>  Yes I still have plain <code>models</code> though the directory is called “db” (as is the namespace), it is literally the schemas that map directly to the database tables, a lot of the tables I did not create and have no control over (other systems) but that I have to deal with (you can definitely feel a lot of Ecto’s limitations when the system was not built ‘by’ ecto…), they hold no data, no processing, not even changesets, they are just the schema.</p>
</li>
<li>
<p><strong>Modules:</strong>  Not modules like elixir modules but modules of functionality, like one is called ‘Accounts’ (within <code>MyServer.Accounts</code>) but there are many.  The Accounts (elixir) module itself just has a set of calls on it, things like <code>confirm_by_login/1</code> that can be called like <code>Accounts.confirm_by_login(login: username, password: the_password)</code> or <code>Accounts.confirm_by_login(pidm: pidm, password: the_password)</code> or <code>Accounts.confirm_by_login(banner_username: username, password: the_password)</code> or <code>Accounts.confirm_by_login(google: google_oauth_struct)</code> or various others, all of which is called via my Ueberauth callbacks from a variety of systems, and it returns either a valid account id (a UUID built from a variety of internal data so it is easily reversible to access various systems) or it returns an exception struct, no it does not raise it, it returns it, that allows me to build up a list of possible errors (using some of expede’s libraries, which are quite nice I must add) and return many error messages instead of just the first that happened to happen.<br>
&nbsp;<br>
The Accounts module has a lot more calls on it to get various information about an account, do things to accounts, etc… etc…<br>
&nbsp;<br>
Most of the modules however (very few calls on Accounts) have a <em>lot</em> of <code>query_</code> and <code>multi_</code> calls, depending on if getting or setting data calls (many ‘getting’ use multi_ as well because access needs to be logged in many cases), such as the Banner module, it has things like (this is the only short one in that whole module, most are utterly ginormous because of the horror’s of accessing this ancient system and needing to join across 10 tables in most cases and a lot more in a few, this one will grow that big over time as well…):</p>
</li>
</ul>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def query_classes(selected \\ :processed, refine) do
    squery =
      from course in DB.Banner.SCBCRSE,
      join: section in DB.Banner.SSBSECT, on: section.ssbsect_subj_code == course.scbcrse_subj_code and section.ssbsect_crse_numb == course.scbcrse_crse_numb and section.ssbsect_ssts_code == "A",
      join: dept in DB.Banner.STVDEPT, on: dept.stvdept_code == course.scbcrse_dept_code

    squery =
      Enum.reduce(refine, squery, fn
        ({:pidm, true}, squery) -&gt;
          join(squery, :inner, [course, section, dept],
            student_course in DB.Banner.SFRSTCR,
            student_course.sfrstcr_term_code == section.ssbsect_term_code and
            student_course.sfrstcr_crn == section.ssbsect_crn
          )
        ({:pidm, pidm}, squery) when is_integer(pidm) -&gt;
          join(squery, :inner, [course, section, dept],
            student_course in DB.Banner.SFRSTCR,
            student_course.sfrstcr_pidm == ^pidm and
            student_course.sfrstcr_term_code == section.ssbsect_term_code and
            student_course.sfrstcr_crn == section.ssbsect_crn
          )
        ({:pidm, pidms}, squery) when is_list(pidms) -&gt;
          join(squery, :inner, [course, section, dept],
            student_course in DB.Banner.SFRSTCR,
            student_course.sfrstcr_pidm in ^pidms and
            student_course.sfrstcr_term_code == section.ssbsect_term_code and
            student_course.sfrstcr_crn == section.ssbsect_crn
          )
        ({:registered, true}, squery) -&gt;
          where(squery, [course, section, dept, student_course], student_course.sfrstcr_rsts_code in ["RA", "RE", "RW"])
        ({:withdrawn, true}, squery) -&gt;
          where(squery, [course, section, dept, student_course], student_course.sfrstcr_rsts_code == "WD")
        ({:department, dept_code}, squery) when is_binary(dept_code) -&gt;
          where(squery, [course, section, dept], course.scbcrse_dept_code == ^dept_code)
        ({:department, dept_code}, squery) when is_list(dept_code) -&gt;
          where(squery, [course, section, dept], course.scbcrse_dept_code in ^dept_code)
        ({:subject, subject_code}, squery) when is_binary(subject_code) -&gt;
          where(squery, [course, section, dept], section.ssbsect_subj_code == ^subject_code)
        ({:subject, subject_code}, squery) when is_list(subject_code) -&gt;
          where(squery, [course, section, dept], section.ssbsect_subj_code in ^subject_code)
        ({:course, course_number}, squery) when is_binary(course_number) -&gt;
          where(squery, [course, section, dept], section.ssbsect_crse_numb == ^course_number)
        ({:course, course_number}, squery) when is_list(course_number) -&gt;
          where(squery, [course, section, dept], section.ssbsect_crse_numb in ^course_number)
        ({semester, year}, squery) when semester in [:spring, :summer, :fall] and is_integer(year) and year&gt;=1900 and year&lt;=9999 -&gt; squery # Handled below in `dyn`
        ({:course_group, %DB.Course.Group{}=course_group}, squery) -&gt;
          squery = if(course_group.dept_codes, do: where(squery, [course, section, dept], course.scbcrse_dept_code in ^course_group.dept_codes), else: squery)
          squery = if(course_group.subject_codes, do: where(squery, [course, section, dept], section.ssbsect_subj_code in ^course_group.subject_codes), else: squery)
          squery = if(course_group.course_numbers, do: where(squery, [course, section, dept], section.ssbsect_crse_numb in ^course_group.course_numbers), else: squery)
          # TODO:  Test the term codes and such too as they will be wanted eventually...
          squery
      end)

    dyn =
      Enum.reduce(refine, false, fn
        ({semester, year}, dyn) when semester in [:spring, :summer, :fall] and is_integer(year) and year&gt;=1900 and year&lt;=9999 -&gt;
          term_code =
            case semester do
              :spring -&gt; "#{year}10"
              :summer -&gt; "#{year}20"
              :fall -&gt; "#{year}30"
            end
          case dyn do
            false -&gt; dynamic([course, section, dept], section.ssbsect_term_code == ^term_code)
            dyn -&gt;  dynamic([course, section, dept], ^dyn or section.ssbsect_term_code == ^term_code)
          end
        (_, dyn) -&gt; dyn
      end)

    squery =
      case dyn do
        false -&gt; squery
        dyn -&gt; where(squery, ^dyn)
      end

    squery =
      case selected do
        :all -&gt; squery
        :processed -&gt;
          case Keyword.get(refine, :pidm) do
            v when v == true or is_list(v) -&gt;
              select(squery, [course, section, dept, student_course], %{
                pidm: student_course.sfrstcr_pidm,
                department_code: course.scbcrse_dept_code,
                department_description: dept.stvdept_desc,
                crn: section.ssbsect_crn,
                subject: section.ssbsect_subj_code,
                course_number: section.ssbsect_crse_numb,
                section_number: section.ssbsect_seq_numb,
                title: fragment("coalesce(?, ?)", section.ssbsect_crse_title, course.scbcrse_title),
                section_begins: section.ssbsect_ptrm_start_date,
                section_ends: section.ssbsect_ptrm_end_date,
                registration_code: student_course.sfrstcr_rsts_code,
                effective_term: course.scbcrse_eff_term,
                _effective_term_rank: fragment("rank() OVER (PARTITION BY ?, ? ORDER BY ? DESC)", section.ssbsect_subj_code, section.ssbsect_crse_numb, course.scbcrse_eff_term),
              })
            _ -&gt;
              select(squery, [course, section, dept], %{
                department_code: course.scbcrse_dept_code,
                department_description: dept.stvdept_desc,
                crn: section.ssbsect_crn,
                subject: section.ssbsect_subj_code,
                course_number: section.ssbsect_crse_numb,
                section_number: section.ssbsect_seq_numb,
                title: fragment("coalesce(?, ?)", section.ssbsect_crse_title, course.scbcrse_title),
                section_begins: section.ssbsect_ptrm_start_date,
                section_ends: section.ssbsect_ptrm_end_date,
                effective_term: course.scbcrse_eff_term,
                _effective_term_rank: fragment("rank() OVER (PARTITION BY ?, ? ORDER BY ? DESC)", section.ssbsect_subj_code, section.ssbsect_crse_numb, course.scbcrse_eff_term),
              })
          end
      end

    query =
      from s in subquery(squery),
      where: s._effective_term_rank == 1

    query
  end
</code></pre>
<p><em>(Wtf, without an extra newline here the forum hides this entire next paragraph?!  Bug with code fences inside bullets??)</em><br>
Now in this one, like most queries in the system, follow this pattern, as a lot of the queries are user-driven and built from custom things to create reports that they pull then a lot of the things that are queried are actually built up from a whole set of refinements (that grows over time as their needs grow over time for more and more reports).  But as you can see the ‘functionality’ is split into specific areas.  Inside of, say, <code>Accounts</code> are more modules like <code>Accounts.PIDM</code> and <code>Accounts.Google</code> and so forth but nothing outside accesses those directly, everything goes through the main interface.</p>
<p>But this is just normal separation of concerns that is pretty universal among ‘many’ programming languages, but I’ve never heard of a Separation of Concerns as Contexts though, nor does it really seem like it should have a special name anyway as it just seems like normal Good Programming?</p>
<p>So yeah, I do not get why ‘Contexts’ are a barrier for newbies to Elixir, this is stuff that any programmer should be doing in any language already.  If anything, giving it such a ‘special name’ is the most confusing part about it, but they themselves are simple.  I really do think calling them what they are, <code>Separation of Concerns</code> would be far more descriptive and less harrowing to newbies as <code>Contexts</code> has no real context.</p>
<p><em>/me has never heard of DDD before Phoenix added the ‘Context’ special stuff, and is wondering if that DDD book is just rehashing 50-year-old separation of concern ideas for a money-grab or something…</em></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36877" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/89">Post #88</a>
	                </div>
	            </div>
              <div id="likers-container-36877" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36877"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #88"></div>
  </section>
</div>
    <div class="postbit" id="36884" data-post-id="36884">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="theangryangel" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/theangryangel/120/5589_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  theangryangel
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m not really sure if my thoughts should really be posted here, or in the other thread, or a new thread. If it’s not appropriate please feel free to move it.</p>
<p>As someone from a self-trained, and more sysadmin background, the <a href="https://forum.elixirforum.com/t/how-would-you-explain-phoenix-contexts-to-a-newbie/5947/8" rel="nofollow">explanation</a> from <a class="mention" href="/u/slashdotdash" rel="nofollow">@slashdotdash</a> is spot on how I feel I should be using contexts. I totally get it in theory. And I suspect many people do.</p>
<p>However in my tiny team of me, myself and I (working on a personal project), I’m finding I’m getting literally anxious about Doing It Right™. Which I know is dumb, but I do wonder if this is how other people feel and what’s causing some of the discussion towards contexts.</p>
<p>I’m hoping a small example might help out where I’m personally getting “stuck” -</p>
<p>Assuming a simple todo web app (because this is 2017, what else?) - users can only see their own todos, unless they’re marked as an admin.</p>
<p>My fictional, web only, system is behind authentication. When a request is made with a token/cookie/whatever currently I can either verify and load the user from the DB, assigning a user struct to the conn (my user struct has some kind of role/permissions/flag/whatever that dictates they’re an admin). Or I can just assign the user id to the conn.</p>
<p>If I just had the user_id on the conn, when I call <code>Todos.list_all</code> I have to load the user from the DB for a second time to determine their permission. My brain screams at the inefficiency of doing it again when I literally just did it to verify the user hasn’t been disabled/whatever. Or if I had a whole user struct loaded, I can just pass that as an argument to <code>list_all</code> - probably using pattern matching to behave differently for admins and standard users.</p>
<p>My anxiety comes in here.</p>
<p>I feel with contexts that I probably shouldn’t really be passing whole user structs around, as I’m coupling my account/login/whatever context to many other contexts. But the other part of my brain tells me querying the DB multiple times for **** I already have, or could have collected when the initial request was made, is dumb. The app isn’t going to become huge. There’s no need to worry about it. By passing around a struct for a user I can use 2 functions with different pattern matching to deal with the permissions differently, and it feels sane. But kinda dirty.</p>
<p>The anxiousness paralyzes me and I have this endless back and forth in my head.</p>
<p>The second part of my anxiety starts coming in my general lack of decent experience with general API design and whilst I totally understand that this is not specific to “contexts”, I suspect is also a factor. Contexts force me to learn and experiment about what is good/better API design. Say I wanted to start paginating the todos, because admins now have a lot of todos (what with being able to see everyone’s). Adding extra arguments for page_number and items_per_page will land me in trouble eventually as I add more and more arguments for specific things. Having a map of arguments feels opaque. The anxiety comes back.</p>
<p>Ultimately I don’t feel like I’m really experienced enough to make these decisions and I end up flipping back and forth between competing designs without ever achieving something.</p>
<p>Edit: These are obviously my personal feelings of inadequacy at play here. I’m not trying to **** on the direction the framework is going. I actually think it’s a good idea, because it will eventually make me better at writing and understanding code (and therefore a better sysadmin I hope). I just feel seeing the same kind of explanations over and over again isn’t really helping me, but adding to my anxiousness of “**** you’re doing it wrong, son”.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36884" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/90">Post #89</a>
	                </div>
	            </div>
              <div id="likers-container-36884" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36884"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #89"></div>
  </section>
</div>
    <div class="postbit" id="36887" data-post-id="36887">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="brightball" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/brightball/120/17192_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  brightball
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Fwiw, one of the things that bothered me about regularly using generators was specifically that you were writing the same stuff over and over. I never understood why that was a good idea.</p>
<p>I get the reason for it, that essentially you are generating the same mappings to fit a REST model for the data…but it always seemed to me that if that was the goal it should be done once with a white labeled list of valid paths. Then, if you needed to modify a part of it create a specific controller for that part.</p>
<p>I realize that wasn’t a popular opinion, but it just always seemed like heavy use of generators was more of an abstraction problem than anything else.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36887" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/91">Post #90</a>
	                </div>
	            </div>
              <div id="likers-container-36887" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36887"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #90"></div>
  </section>
</div>
    <div class="postbit" id="36937" data-post-id="36937">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="cmkarlsson" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cmkarlsson/120/23000_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  cmkarlsson
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="89" data-topic="5929">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>But this is just normal separation of concerns that is pretty universal among ‘many’ programming languages, but I’ve never heard of a Separation of Concerns as Contexts though, nor does it really seem like it should have a special name anyway as it just seems like normal Good Programming?</p>
</blockquote>
</aside>
<p>Yes, and if anything this is something that should be pushed. This is not only for phoenix that we are discussing here but for any elixir app so a best practice approach for elixir that can be applied to phoenix would be great</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36937" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/92">Post #91</a>
	                </div>
	            </div>
              <div id="likers-container-36937" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36937"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #91"></div>
  </section>
</div>
    <div class="postbit" id="36940" data-post-id="36940">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="brightball" data-post="91" data-topic="5929">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/brightball/48/17192_2.png" class="avatar"> brightball:</div>
<blockquote>
<p>but it always seemed to me that if that was the goal it should be done once with a white labeled list of valid paths.</p>
</blockquote>
</aside>
<p>I’m a beginner in this web stuff, but the little experience I have doesn’t necessary agree with you.</p>
<p>What you say seems superficially like a good idea, but in practice there are lots of little details you want to customize. In something like python you’d do it with class inheritance and method/attribute overrides, but in my very limited experience you end up almost rewriting the whole code. If you’re getting too deep into the bowels of the original class, you should probably rewrite ir yourself.</p>
<p>You could probably use elixir macros to mimic something like class inheritance, but in the end, the most flexible “abstraction” is a mix task that generates editable code. Not the most concise abstraction, sure, but it is flexible.</p>
<p>When I first got into Elixir and Phoenix, these generators rubbed me the wrong way, because they weren’t promoting “code reuse” or using clever abstractions, but now I’m not so sure anymore. I’m starting to see the value of generated text files as a mechanism for extensibility.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="36940" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/contexts-a-barrier-too-high-for-newbies/5929/93">Post #92</a>
	                </div>
	            </div>
              <div id="likers-container-36940" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="36940"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #92"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/5929/load_more?page=10">Load more posts (76 remaining)</a>
</div></template></turbo-stream>