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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sodapopcan" data-post="11" data-topic="54624">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sodapopcan/48/34668_2.png" class="avatar"> sodapopcan:</div>
<blockquote>
<p><a href="https://viewcomponent.org/" rel="noopener nofollow ugc">View Component </a> which is nicer than partials but it’s no heex</p>
</blockquote>
</aside>
<p>I hear you. We use <code>ViewComponent</code> on my current job and its ok, what I <em>really</em> dont like is that we use <a href="https://haml.info/" rel="noopener nofollow ugc">haml</a>.<br>
Going from heex + vscode plugins to haml is pretty sad, the developer experience is so much worse</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282696" 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/phoenix-for-rails-developers/54624/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-282696" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282696"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="282711" data-post-id="282711">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Not to derail this thread too much but I used to be really into Slim until I wasn’t.  One of my biggest problems was that back in a pre-Tailwindeque world I couldn’t tell my markup from my css at a glance—they had an almost identical shape!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282711" 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/phoenix-for-rails-developers/54624/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-282711" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282711"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="282944" data-post-id="282944">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve been doing Rails since 1.x. I like to tell people new to Phoenix that it’s most like Rails 2.x. Kinda back when Rails was simple (routes that sends requests to a controller/action, and also the whole “restful resources” thing).</p>
<p>That said, I’m also starting to fall more and more into the camp of everything should be LiveView; there’s no point in doing controller/actions anymore (aside from APIs), even if you’re just making basic CRUD pages. Even beyond no point, I actually think it’s <em>easier</em> to make basic CRUD pages in LV now.</p>
<p>To get people’s foot in the door with LV, I do a 10 min live coding session where I make a route, then setup a basic LV and show how to do assigns and wire up the HTML, etc. Then try to show the difference between connected? mount and dead mount and how it relates to progressive loading.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282944" 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/phoenix-for-rails-developers/54624/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-282944" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282944"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="282945" data-post-id="282945">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m in the “everything should be a LiveView” camp as well so long as your page doesn’t need to work without JS.  Making forms work without JS in LiveView is a pain and not worth the effort imo.   But otherwise, I don’t see the point in not doing everything as LiveViews.  I agree that basic CRUD feels simpler in LV.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282945" data-batch-url="/posts/batch_likers">
                        4
                      </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/phoenix-for-rails-developers/54624/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-282945" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282945"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="282969" data-post-id="282969">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think blitzjs or remix gets you about the same simplicity, just using js/node instead and no websockets needed (I may be wrong on websockets). I haven’t used them, so this is just an abstract observation.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="282969" 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/phoenix-for-rails-developers/54624/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-282969" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="282969"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="284249" data-post-id="284249">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<div class="youtube-onebox lazy-video-container" data-video-id="uPWMBDTPMkQ" data-video-title="The Rubyist's Survival Guide to Elixir and Phoenix (expanded and updated for 2023)" data-video-start-time="" data-provider-name="youtube">
  <a href="https://www.youtube.com/watch?v=uPWMBDTPMkQ" target="_blank" class="video-thumbnail" rel="noopener nofollow ugc">
    <img class="youtube-thumbnail" src="https://img.youtube.com/vi/uPWMBDTPMkQ/maxresdefault.jpg" title="The Rubyist's Survival Guide to Elixir and Phoenix (expanded and updated for 2023)" width="690" height="388">
  </a>
</div>
<p>
Relevant video I just got on my ruby weekly mailing list (I havent watched it yet)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="284249" 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/phoenix-for-rails-developers/54624/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-284249" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="284249"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="286524" data-post-id="286524">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I worked full-time with Rails for around five years before switching to Elixir and Phoenix. Haven’t regretted the decision for one second - I don’t miss Rails at all.</p>
<p>If you’re coming to Phoenix from a Rails background, then the best course in my humble opinion is the one I wrote: <a href="http://phoenixonrails.com/" rel="noopener nofollow ugc">Phoenix on Rails</a>. I apologise for the self-promotion, but you can use the code <strong>ELIXIRFORUM</strong> to get a $10 discount.</p>
<p>To answer your question more directly, some of the main things that helped me were:</p>
<ul>
<li>
<p>Taking the time to learn Elixir itself <em>before</em> diving into Phoenix. Elixir is much more different from Ruby than it appears at first; the languages use similar syntax but their underlying design is very different. I initially tried to learn Elixir “alongside Phoenix” but it was confusing and too much to learn at once.</p>
</li>
<li>
<p>Understanding that (as someone else said above) Phoenix isn’t nearly as opinionated as Rails is. If all you know is Rails, your initial reaction to solving a problem is often to try and figure out the “Rails way” of doing it - like there’s a single best practice that everyone should follow. This isn’t the case nearly as often in Phoenix. In particular, your “context” modules are just regular Elixir modules. In Rails, you build a Rails app; in Phoenix you build an <em>Elixir</em> application where Phoenix just happens to be the part that handles the “web” side of things (and Ecto handles data persistence/validation etc.)</p>
<p>This might seem like a bad thing, but I think over time you’ll come to appreciate Phoenix’s flexibility. If anything Rails is too opinionated - it’s too inflexible, and the “Rails way” breaks down and becomes a mess as soon as you try to do something that doesn’t fit neatly within Rails’s conventions.</p>
</li>
<li>
<p>Before I learned Ecto I already had a good knowledge of SQL and knew how to write a complicated SQL query. This definitely helped me understand <code>Ecto.Query</code>, as its DSL follows SQL quite closely.</p>
</li>
</ul>
<p>I think Ecto is the hardest thing to learn when coming from Rails - not because it’s difficult on its own terms, just that it’s very different from ActiveRecord; probably the part of Phoenix’s stack that feels the most unfamiliar to a Rails dev. (I also think that Ecto’s MUCH better designed than ActiveRecord and leads to far cleaner and more maintainable code, but that’s another post.) Before you try to build a complicated Phoenix app, I recommend sitting down with the different parts of Ecto and getting to grips with how they work, and how to do in Ecto the basic things you already know how to do in ActiveRecord. (For starters, I wrote <a href="https://dev.to/arrowsmith/activerecord-vs-ecto-querying-the-database-4o9g" rel="noopener nofollow ugc">this cheatsheet</a>)  for learning <code>Ecto.Query</code> when you know ActiveRecord.)</p>
<p>Some other small things that are bound to trip you up, so be aware:</p>
<ul>
<li>in HEEx you need to write <code>&lt;%= if </code> instead of <code>&lt;% if</code>.</li>
<li>uniqueness validations work differently; look up <code>unique_constraint</code>.</li>
<li>Ecto associations aren’t loaded by default (you need to explicitly <code>preload</code> so you can’t accidentally introduce an N+1 issue, as is far too easy in Rails.)</li>
</ul>
<p>I’d also recommend taking the time to understand <code>Plug</code> sooner rather than later. At a glance <code>Plug</code> is similar to <code>Rack</code>, except Rack is kind of hidden from you and you can spend years using Rails without ever needing to think about Rack. <code>Plug</code> is much more “up front and centre” in Phoenix and an important part of your stack - you don’t need to understand it from the very beginning, but don’t neglect it.</p>
<p>That’s all I can think of for now. (As for the book <em>Phoenix for Rails Developers</em> that was mentioned above - I read it when I was getting started but honestly I was very disappointed by it, not least because it’s very out of date. Phoenix has changed a lot since 1.3. My disappointment with that book was one of the reasons why I eventually decided to create <a href="http://phoenixonrails.com/" rel="noopener nofollow ugc">Phoenix on Rails</a>.)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="286524" 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/phoenix-for-rails-developers/54624/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-286524" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286524"
                     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 #17"></div>
  </section>
</div>
    <div class="postbit" id="286631" data-post-id="286631">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>It has been years since I wrote any Ruby code, but one thing I do miss to this day is being able to do stuff like <code>1.day.ago</code> to get a date object that represents yesterday. Coding patterns/structures that resemble natural language are such a simple yet powerful concept that I’m surprised more languages haven’t tried to implement them.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="286631" 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/phoenix-for-rails-developers/54624/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-286631" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="286631"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>