<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Juan Ferrari</title>
    <description>The latest articles on DEV Community by Juan Ferrari (@juannferrari).</description>
    <link>https://dev.to/juannferrari</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F376346%2F06c04960-0c9e-4d4a-aa8b-d7dfa9461cfb.jpeg</url>
      <title>DEV Community: Juan Ferrari</title>
      <link>https://dev.to/juannferrari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/juannferrari"/>
    <language>en</language>
    <item>
      <title>Form object patterns in Rails: Stop creating services for everything with YAAF</title>
      <dc:creator>Juan Ferrari</dc:creator>
      <pubDate>Mon, 11 Jan 2021 16:04:40 +0000</pubDate>
      <link>https://dev.to/rootstrap/form-object-patterns-in-rails-stop-creating-services-for-everything-with-yaaf-409o</link>
      <guid>https://dev.to/rootstrap/form-object-patterns-in-rails-stop-creating-services-for-everything-with-yaaf-409o</guid>
      <description>&lt;h2 id="h-working-with-large-controllers"&gt;Working with large controllers&lt;/h2&gt;

&lt;p&gt;How many times have you encountered large controller methods? If you are &lt;em&gt;lucky&lt;/em&gt; like me, probably many times.&lt;/p&gt;

&lt;p&gt;One of the most common practices to start refactoring a long controller is to move the code to a service.&lt;/p&gt;

&lt;p&gt;Services are great, and if we code them in an atomic way, they will be easy to test and understand. But the problem is when we use the services it's like using a &lt;em&gt;Swiss Army knife&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;-"Hey, I don't know how to properly refactor this piece of code" 
-"Dude, just do a new service"&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;But no!&lt;/strong&gt;, making a new service is not always the best option. In some cases, we are &lt;em&gt;reinventing the wheel&lt;/em&gt; and maybe there is a pattern that already fits with our needs.&lt;/p&gt;

&lt;p&gt;So here comes &lt;strong&gt;YAAF&lt;/strong&gt;, yet another active form to save our day. &lt;strong&gt;YAAF&lt;/strong&gt; is a gem that lets you create form objects using Rails in an easy and friendly way. It makes use of &lt;code&gt;ActiveRecord&lt;/code&gt; and &lt;code&gt;ActiveModel&lt;/code&gt; features, to provide you with a form object that behaves like a Rails model while remaining completely configurable.&lt;/p&gt;

&lt;h2 id="h-when-to-use-yaaf"&gt;When to use YAAF?&lt;/h2&gt;

&lt;p&gt;Let's imagine that we have an API endpoint that saves a new post on our database. A post has a title, body, publisher, and could also have tags and a category.&lt;/p&gt;

&lt;p&gt;Tags and categories can be created as soon as the publisher sends the post. (If our inputs don't find the correct tag or category, they will let the user write the name of a new one).&lt;/p&gt;

&lt;p&gt;So, in the worst-case scenario, our controller could have something like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Api::V1::PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Api&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;V1&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ApiController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="vi"&gt;@post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:tags&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="no"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_create_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:category_name&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
        &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:category_name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="vi"&gt;@post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;


  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post_params&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:post&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:publisher_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:category_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks terrible, right? Maybe our first thought about that piece of code is to make a refactoring that moves the creation of the post to a service named &lt;code&gt;PostCreationService&lt;/code&gt;. This could be useful and might be used in the future in another part of the system. But, what have we said about &lt;em&gt;reinventing the wheel&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;When using &lt;strong&gt;YAAF&lt;/strong&gt;, we should create a new &lt;code&gt;PostForm&lt;/code&gt; class that is going to encapsulate all the logic of post creation and related models inside it. And it is very simple to implement it! Just look at this code:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/forms/post_form.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostForm&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationForm&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:category_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:tags&lt;/span&gt;
  &lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="ss"&gt;:amount_of_tags&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@models&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_tags&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compact&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new_post&lt;/span&gt;
    &lt;span class="vi"&gt;@new_post&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;
      &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_tags&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;category&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;category_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;

    &lt;span class="vi"&gt;@category&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_initialize_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;category_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post_tags&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;

    &lt;span class="vi"&gt;@post_tags&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="no"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_initialize_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;amount_of_tags&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;between?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"You can't assign more than three tags to a post"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We have also added a custom validation named &lt;code&gt;amount_of_tags&lt;/code&gt;, as YAAF helps us to encapsulate business rules in our Form Object.&lt;/p&gt;

&lt;p&gt;And then, in our controller, we have the following:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Api::V1::PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Api&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;V1&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ApiController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PostForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_form_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save!&lt;/span&gt;
    &lt;span class="vi"&gt;@post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post_form_params&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:category_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;tags: &lt;/span&gt;&lt;span class="sx"&gt;%i[id name]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;post: &lt;/span&gt;&lt;span class="sx"&gt;%i[title body publisher_id category_id]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Having an &lt;code&gt;ApplicationForm&lt;/code&gt; which inherits from &lt;code&gt;YAAF::Form&lt;/code&gt; is a good practice.&lt;/p&gt;

&lt;p&gt;That's it, now we have a &lt;code&gt;PostForm&lt;/code&gt; which encapsulates all the persistency logic of post/tags/categories, leaving our controller and models clean, with an easy to follow code.&lt;/p&gt;

&lt;p&gt;Another good thing is that &lt;strong&gt;YAAF&lt;/strong&gt; provides a similar API to &lt;code&gt;ActiveModel&lt;/code&gt; models, so you can treat them interchangeably.&lt;/p&gt;

&lt;h2 id="h-why-not-a-service-or-poro-s"&gt;Why not a Service or PORO's?&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Making customized Services or PORO's could be disorganized&lt;/strong&gt; if you're working in a team.&lt;/li&gt;
&lt;li&gt;YAAF helps you to apply the &lt;strong&gt;Form Pattern&lt;/strong&gt; in an easy way.&lt;/li&gt;
&lt;li&gt;YAAF is only &lt;strong&gt;64 lines long&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It's &lt;strong&gt;well tested and maintained&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It helps you keep your models, views, and controllers thin by providing a better place to put business logic. In the end, this will &lt;strong&gt;improve the quality of your codebase and make it easier to maintain and extend&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;And a lot &lt;strong&gt;&lt;a href="https://github.com/rootstrap/yaaf"&gt;more&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="h-summary"&gt;Summary&lt;/h2&gt;

&lt;p&gt;Well, if you've got this far, I hope this article helps you to integrate &lt;strong&gt;YAAF&lt;/strong&gt; in your project, while also helping you use the &lt;code&gt;FormObject&lt;/code&gt; Pattern to make your code even better. You can see more examples &lt;strong&gt;&lt;a href="https://github.com/rootstrap/yaaf"&gt;here&lt;/a&gt;&lt;/strong&gt;. &lt;strong&gt;YAAF&lt;/strong&gt; is open-source and is open to receive new contributions.&lt;/p&gt;

&lt;p&gt;So check it out and see what you think!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>opensource</category>
      <category>codequality</category>
    </item>
    <item>
      <title>The 8 Best Visual Studio Code Extensions for Programming Ruby</title>
      <dc:creator>Juan Ferrari</dc:creator>
      <pubDate>Thu, 01 Oct 2020 23:33:58 +0000</pubDate>
      <link>https://dev.to/juannferrari/the-8-best-visual-studio-code-extensions-for-programming-ruby-1h2g</link>
      <guid>https://dev.to/juannferrari/the-8-best-visual-studio-code-extensions-for-programming-ruby-1h2g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was originally created for the &lt;a href="https://www.rootstrap.com/blog/the-8-best-visual-studio-code-extensions-for-programming-ruby/" rel="noopener noreferrer"&gt;Rootstrap blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Choosing a Text Editor&lt;/h2&gt;

&lt;p&gt;It may be a tough decision, as a programmer, to choose a text editor, since it will be your main tool to do your work, and you will use it every day in your work-life.&lt;/p&gt;

&lt;p&gt;Everybody has their favorite text editor, I have known people who use &lt;strong&gt;&lt;a href="https://www.vim.org/" rel="noopener noreferrer"&gt;Vim&lt;/a&gt;, &lt;a href="https://notepad-plus-plus.org/" rel="noopener noreferrer"&gt;Notepad++&lt;/a&gt;, &lt;a href="https://www.sublimetext.com/" rel="noopener noreferrer"&gt;Sublime Text&lt;/a&gt;, &lt;a href="https://atom.io/" rel="noopener noreferrer"&gt;Atom&lt;/a&gt;&lt;/strong&gt;, and many others.&lt;/p&gt;

&lt;p&gt;I have tried different text editors in my career and was always looking for the perfect one. At first, I started with Sublime Text, later the pretty UI of Atom hooked me, and for the last year I have been coding with &lt;strong&gt;Visual Studio Code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I was enjoying Atom, but in some cases, my computer at the time couldn't handle it very well and it was getting a bit laggy to open the text editor or work with it. So a friend of mine told me that maybe Visual Studio Code could fit my needs, and he was right.&lt;/p&gt;

&lt;h1&gt;Visual Studio Code Extensions&lt;/h1&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens" rel="noopener noreferrer"&gt;GitLens&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This extension includes a lot of cool functionalities of Git in Visual Studio Code: "GitLens simply helps you &lt;strong&gt;better understand code&lt;/strong&gt;" says Eric Amodio, the creator of the extension.&lt;/p&gt;

&lt;p&gt;I love Gitlens because it allows me to detect who wrote the code that I am reading, and this is really useful because when I have doubts about the code, I know who to talk to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An unobtrusive current line blame annotation at the end of the line with detailed blame information accessible via hovers&lt;/li&gt;
&lt;li&gt;Authorship code lens showing the most recent commit and # of authors to the top of files and/or on code blocks&lt;/li&gt;
&lt;li&gt;A status bar blame annotation showing author and date for the current line&lt;/li&gt;
&lt;li&gt;On-demand gutter blame annotations, including a heatmap, for the whole file&lt;/li&gt;
&lt;li&gt;On-demand gutter heatmap annotations to show how recently lines were changed, relative to all the other changes in the file (hot vs. cold)&lt;/li&gt;
&lt;li&gt;On-demand recent changes annotations to highlight lines changed by the most recent commit&lt;/li&gt;
&lt;li&gt;And much &lt;a href="https://gitlens.amod.io/#features" rel="noopener noreferrer"&gt;more&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Fgitlens-preview.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Fgitlens-preview.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This extension provides enhanced Ruby language and debugging support. One of the coolest things about this extension is the syntax support to our ruby files, so this is a &lt;strong&gt;must-have&lt;/strong&gt; if you are a Ruby developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic Ruby environment detection with support for rvm, rbenv, chruby, and asdf&lt;/li&gt;
&lt;li&gt;Lint support via RuboCop, Standard, and Reek&lt;/li&gt;
&lt;li&gt;Format support via RuboCop, Standard, Rufo, and RubyFMT&lt;/li&gt;
&lt;li&gt;Semantic code folding support&lt;/li&gt;
&lt;li&gt;Semantic highlighting support&lt;/li&gt;
&lt;li&gt;Basic Intellisense support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Fvsrubycode-1024x800.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Fvsrubycode-1024x800.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=castwide.solargraph" rel="noopener noreferrer"&gt;Ruby Solargraph&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Another &lt;strong&gt;vital&lt;/strong&gt; extension if you are a Ruby developer, which gives Visual Studio Code some features that can be found in IDE's like "Go to definition" for classes, modules, and methods. Also provides documentation and code completion. If you are learning Ruby, this extension will help you a lot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context-aware suggestions and documentation for the Ruby core&lt;/li&gt;
&lt;li&gt;Detection of some variable types and method return values (e.g., String.new. returns String instance methods)&lt;/li&gt;
&lt;li&gt;Identification of local, class, and instance variables within the current scope&lt;/li&gt;
&lt;li&gt;Find references and rename symbols (experimental as of solargraph gem v0.22.0)&lt;/li&gt;
&lt;li&gt;Support for gems&lt;/li&gt;
&lt;li&gt;Near-complete support for the Ruby core and stdlib&lt;/li&gt;
&lt;li&gt;Partial support for Ruby on Rails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Frubysolargraph.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Frubysolargraph.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=misogi.ruby-rubocop" rel="noopener noreferrer"&gt;ruby-rubocop&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Having RuboCop configured in your ruby project will help you maintain the quality of the code, especially if your project is being developed by a team. This extension will let you autoformat and correct your code basing it the directives written in the .rubucop.yml file. With only a key shortcut your code will be formatted in a second, it's fast, it's good, it's an &lt;strong&gt;essential&lt;/strong&gt; extension.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lint by executing the command "Ruby: lint by rubocop" (cmd+shift+p and type command)&lt;/li&gt;
&lt;li&gt;Auto invoke when saving file&lt;/li&gt;
&lt;li&gt;Auto correct command "Ruby: autocorrect by rubocop"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Frubyrubocop.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Frubyrubocop.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This extension will help you to format the code of Javascript, HTML, CSS, JSON, and many more files. Is simple and quick, is not as configurable as other code-formatter extensions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports many languages&lt;/li&gt;
&lt;li&gt;You press save and code is formatted&lt;/li&gt;
&lt;li&gt;No need to discuss style in code review&lt;/li&gt;
&lt;li&gt;Saves you time and energy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=emmanuelbeziat.vscode-great-icons" rel="noopener noreferrer"&gt;VSCode Great Icons&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;A very simple one, adds icons to your files and it personally helps me a lot to know instantly which kind of file I'm viewing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Fvscodegreaticons-1024x670.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rootstrap.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F08%2Fvscodegreaticons-1024x670.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Switching from Atom to Visual Studio Code&lt;/h2&gt;

&lt;p&gt;I missed the Atom shortcut keymap so much when I made the switch, but here is your salvation.&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.atom-keybindings" rel="noopener noreferrer"&gt;Atom Keymap&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This extension ports popular Atom keyboard shortcuts to Visual Studio Code and helps to make the switch between code editors a lot easier.&lt;/p&gt;

&lt;h2&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=akamud.vscode-theme-onedark" rel="noopener noreferrer"&gt;Atom One Dark Theme&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;And the last extension that I will share with you is an aesthetic one, when I started using Visual Studio Code I missed the theme that Atom provides, so this extension fixed that problem for me.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;These are currently my favorite extensions for Visual Studio Code. I hope this famous code editor will help you improve your experience. Please feel free to comment below if you have any other extension recommendations!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>vscode</category>
      <category>codequality</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to customize the display name of dynamic ActiveAdmin search filters</title>
      <dc:creator>Juan Ferrari</dc:creator>
      <pubDate>Tue, 14 Jul 2020 17:00:56 +0000</pubDate>
      <link>https://dev.to/juannferrari/how-to-customize-the-display-name-of-dynamic-activeadmin-search-filters-2gdp</link>
      <guid>https://dev.to/juannferrari/how-to-customize-the-display-name-of-dynamic-activeadmin-search-filters-2gdp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This post was originally created for the &lt;a href="https://www.rootstrap.com/blog/how-to-customize-the-display-name-of-dynamic-activeadmin-search-filters/"&gt;Rootstrap blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Working with ActiveAdmin&lt;/h2&gt;

&lt;p&gt;At Rootstrap, my first assignment was to develop a Ruby on Rails application which uses ActiveAdmin (with ActiveAdmin Addons) as a framework to implement the user interface.&lt;/p&gt;

&lt;p&gt;I had never used ActiveAdmin before and I found myself reading a lot of documentation of the gem, in some cases, the documentation was not enough. For example, when I tried to display a custom name on an AJAX's search select filter at first it was a little tricky. So today I will show you how to do it, in the end, it's really simple!&lt;/p&gt;

&lt;h2&gt;Showing our custom display_name&lt;/h2&gt;

&lt;p&gt;In this tutorial, you will learn how to customize the &lt;code&gt;display_name&lt;/code&gt; of a &lt;code&gt;search_select&lt;/code&gt; the filter provided by ActiveAdmin Addons.&lt;/p&gt;

&lt;p&gt;Before starting we have to include in our &lt;code&gt;Gemfile&lt;/code&gt; the &lt;code&gt;activeadmin&lt;/code&gt; gem and &lt;code&gt;activeadmin-addons&lt;/code&gt; gem.&lt;/p&gt;

&lt;p&gt;In this example we are going to use a search select to filter people and search a person, our &lt;code&gt;person&lt;/code&gt; model has two fields named &lt;code&gt;first_name&lt;/code&gt; and &lt;code&gt;last_name&lt;/code&gt;, and we want to display the full name of the person when we are searching it. The &lt;code&gt;full_name&lt;/code&gt; is the concatenation of &lt;code&gt;first_name&lt;/code&gt; and &lt;code&gt;last_name&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Steps to show our custom display_name&lt;/h2&gt;

&lt;h3&gt;Create a Search Select&lt;/h3&gt;

&lt;p&gt;First of all, you should create a search select input in ActiveAdmin. This can be used in many places but in this example, we are going to use it in a filter. To do that, go to an ActiveAdmin view and put this code on it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;      filter :person_id,
             as: :search_select_filter,
             fields: %i[first_name last_name],
             display_name: :full_name&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(If you are going to use this on a form you have to change &lt;code&gt;search_select_filter&lt;/code&gt; to &lt;code&gt;search_select&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The fields array indicates the fields that are used to filter, our input will be matched with the &lt;code&gt;first_name&lt;/code&gt; of a person or their &lt;code&gt;last_name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;display_name&lt;/code&gt; is the field that our filter is showing to us meanwhile we search.&lt;/p&gt;

&lt;h3&gt;Setting up the returned JSON&lt;/h3&gt;

&lt;p&gt;The search select input is requesting a JSON meanwhile the user is searching for a person, for example in this case the filter will be doing requests to this endpoint &lt;code&gt;/admin/people&lt;/code&gt; and retrieving a JSON showing all model attributes from a person. This is auto-generated by ActiveAdmin, but we can overwrite the response.&lt;/p&gt;

&lt;p&gt;In this application we are using JBuilder to render JSON response so we have to create a file in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;views/admin/(model_name_pluralized)/index.json.jbuilder&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In our example, the view created is in&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;views/admin/people/index.json.jbuilder&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this file we can write the custom JSON that we want to retrieve for example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;json.array!(@people) do |person|
  json.extract! person, :id, :full_name
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Attention: &lt;code&gt;full_name&lt;/code&gt; is a method on &lt;code&gt;person&lt;/code&gt; model, we have to write that method in the model and not in a decorator because if we are using this &lt;code&gt;search_select&lt;/code&gt; in edit/new view an error will raise when validation fails, ActiveAdmin will call a method from &lt;code&gt;person&lt;/code&gt; model named &lt;code&gt;full_name&lt;/code&gt; and not from the decorator.&lt;/p&gt;

&lt;h3&gt;Writing the full_name method&lt;/h3&gt;

&lt;p&gt;Just write the method that we want in &lt;code&gt;app/models/person.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def full_name
    [first_name, last_name].compact.join(' ')
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now our search select input is ready to display the person full name!&lt;/p&gt;

&lt;h2&gt;What we learned about Search Select Inputs?&lt;/h2&gt;

&lt;p&gt;In this article, we learned how to display a custom field in our search select inputs. This will help us to give better search feedback to the user and it can be used in many different scenarios. It also helps us take control of the JSON returned by ActiveAdmin to the input (by default, all attributes are returned and maybe that's not good for us).&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/platanus/activeadmin_addons/blob/master/docs/select2_search.md"&gt;Select2_Search&lt;/a&gt; &lt;a href="https://github.com/activeadmin/activeadmin/"&gt;ActiveAdmin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>ajax</category>
      <category>activeadmin</category>
    </item>
    <item>
      <title>It's has been a year since my first gem was published. What I have learned so far?</title>
      <dc:creator>Juan Ferrari</dc:creator>
      <pubDate>Sun, 03 May 2020 17:48:17 +0000</pubDate>
      <link>https://dev.to/juannferrari/it-s-has-been-a-year-since-my-first-gem-was-published-what-i-have-learned-so-far-4mnc</link>
      <guid>https://dev.to/juannferrari/it-s-has-been-a-year-since-my-first-gem-was-published-what-i-have-learned-so-far-4mnc</guid>
      <description>&lt;p&gt;Things happen &lt;strong&gt;fast&lt;/strong&gt;! One year ago I was a Junior Developer building a really &lt;em&gt;small&lt;/em&gt; gem for Ruby on Rails &lt;strong&gt;&lt;a href="https://github.com/JuannFerrari/sort_n_params"&gt;sort_n_params&lt;/a&gt;&lt;/strong&gt;, my first contribution as a developer to the open source's scene.&lt;/p&gt;

&lt;h2&gt;
  
  
  What have I learned since then?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.- It's always good to build &lt;em&gt;things&lt;/em&gt;, no matter how small.
&lt;/h3&gt;

&lt;p&gt;If you have an idea, &lt;strong&gt;build it up&lt;/strong&gt;. Ask for help from your colleagues if you're stuck -- it doesn't matter if your idea sounds silly or small, building and finishing things helps us improve our skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.- Publish and share your work!
&lt;/h3&gt;

&lt;p&gt;The solution you have found may be useful to others, so share it. Maybe someone else will help you improve your solution. &lt;strong&gt;Don't be shy!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mlqfJYNu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/638/1%2AsLTZaWc3aktXcGaC3OjGUw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mlqfJYNu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/638/1%2AsLTZaWc3aktXcGaC3OjGUw.png" alt="Image One" width="638" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.- An example of what you can do
&lt;/h3&gt;

&lt;p&gt;Maybe you're looking for your first job in the industry, but a lot of interviewers ask you about previous experience. Having your own project published in &lt;strong&gt;Github&lt;/strong&gt; or deployed in &lt;strong&gt;Heroku&lt;/strong&gt; will help you prove that you already have some experience with coding.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.- The importance of testing and continuous integration
&lt;/h3&gt;

&lt;p&gt;Technology is advancing rapidly and it is very possible that our code will change in the near future. Testing our code prevents problems and saves time and setting up a continuous integration service like &lt;strong&gt;&lt;a href="https://travis-ci.org/"&gt;TravisCI&lt;/a&gt;&lt;/strong&gt; to our repository ensures the proper functioning of our project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jvQnqGuZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/en/5/55/King-Size_Homer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jvQnqGuZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/en/5/55/King-Size_Homer.png" alt="Image Two" width="363" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5.- It's good to contribute to the Open Source scene
&lt;/h3&gt;

&lt;p&gt;It doesn't matter if you only make a small contribution, it will help you improve and meet a world that is growing every day&lt;/p&gt;

&lt;h3&gt;
  
  
  6.- Publishing a gem is really easy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Don't be scared!&lt;/strong&gt; If you want to publish a new gem, there are plenty of tutorials on the web and it doesn't take long to do so.&lt;/p&gt;

&lt;p&gt;I hope my experience encourages you to make your own gems and projects. &lt;strong&gt;Let's code!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>opensource</category>
      <category>github</category>
    </item>
  </channel>
</rss>
