<?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: Abd ElRahman Shawareb</title>
    <description>The latest articles on DEV Community by Abd ElRahman Shawareb (@ashawareb).</description>
    <link>https://dev.to/ashawareb</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%2F425371%2F0cc57d46-0eca-4474-9656-0904e12835e8.jpg</url>
      <title>DEV Community: Abd ElRahman Shawareb</title>
      <link>https://dev.to/ashawareb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashawareb"/>
    <language>en</language>
    <item>
      <title>Arel and Ruby on Rails</title>
      <dc:creator>Abd ElRahman Shawareb</dc:creator>
      <pubDate>Sun, 05 Mar 2023 13:40:43 +0000</pubDate>
      <link>https://dev.to/ashawareb/arel-and-ruby-on-rails-58m3</link>
      <guid>https://dev.to/ashawareb/arel-and-ruby-on-rails-58m3</guid>
      <description>&lt;p&gt;Hi RoR folks! Hope you are all doing well and celebrating Ruby's birthday!&lt;/p&gt;

&lt;p&gt;Today in this post we are gonna talk about &lt;strong&gt;Arel&lt;/strong&gt; and here is a list of what we are gonna discuss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Arel?&lt;/li&gt;
&lt;li&gt;History of Arel&lt;/li&gt;
&lt;li&gt;Advantages of using Arel&lt;/li&gt;
&lt;li&gt;Arel basic syntax&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Arel?
&lt;/h2&gt;

&lt;p&gt;Arel is a library that is being used to help us to write SQL queries in a much &lt;strong&gt;easier&lt;/strong&gt;, more &lt;strong&gt;readable&lt;/strong&gt;, and &lt;strong&gt;cleaner&lt;/strong&gt; way. Also, it helps us to write both simple and complex queries.&lt;/p&gt;




&lt;h2&gt;
  
  
  History of Arel
&lt;/h2&gt;

&lt;p&gt;Arel was introduced in Rails 3 but it is now bundled into the &lt;a href="https://rubygems.org/gems/activerecord"&gt;Active Record&lt;/a&gt; gem, and maintained in the &lt;a href="https://github.com/rails/rails"&gt;rails/rails&lt;/a&gt; repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Advantages of using Arel
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;h4&gt;
  
  
  Readability
&lt;/h4&gt;

&lt;p&gt;Since all SQL queries are strings, it may be hard to read, edit, or break down a complex query.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;
  
  
  Reusability
&lt;/h4&gt;

&lt;p&gt;It’s much easier to reuse Arel queries as they are made up of interlinking nodes – a safer alternative than string interpolation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;
  
  
  Reliability
&lt;/h4&gt;

&lt;p&gt;If we join another table, our query will immediately break due to the ambiguity of the id column. Even if we qualify the columns with the table name, this will break as well if Rails decides to alias the table name.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Arel basic syntax
&lt;/h2&gt;

&lt;h4&gt;
  
  
  - Arel Table
&lt;/h4&gt;

&lt;p&gt;TTo start creating queries, we need to decide which Model we are going to query on. Then, we need to interact with the Arel Table for that Model and this could be done by using the &lt;code&gt;arel_table&lt;/code&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arel_table&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here there is an &lt;code&gt;Arel::Table&lt;/code&gt; object created for that table we are going to work on. After that object is created for that data table, Arel converts each column of that Table into an &lt;code&gt;Arel::Node&lt;/code&gt; that we can execute different methods that are supported by this library on it. The most common methods in Arel are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Equal &lt;strong&gt;&lt;em&gt;(eq)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Not Equal &lt;strong&gt;&lt;em&gt;(not_eq)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Greater Than &lt;strong&gt;&lt;em&gt;(gt)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Less Than &lt;strong&gt;&lt;em&gt;(lt)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Greater Than Or Equal &lt;strong&gt;&lt;em&gt;(gteq)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Less Than Or Equal &lt;strong&gt;&lt;em&gt;(lteq)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Or &lt;strong&gt;&lt;em&gt;(or)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;And &lt;strong&gt;&lt;em&gt;(and)&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; To see all Arel predications you can run: &lt;code&gt;Arel::Predications.instance_methods&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  - Where queries
&lt;/h4&gt;

&lt;p&gt;We can say that more than 75% of all the queries are built using &lt;code&gt;where&lt;/code&gt; method cause it's used to filter our data and select a specific part based on a specific true condition. Since &lt;code&gt;where&lt;/code&gt; method can take different kinds of arguments, we can pass custom-built Arel queries to it and this could be so powerful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; To break a query to use Arel, there's a good rule to break out a method anywhere the word &lt;code&gt;AND&lt;/code&gt; or &lt;code&gt;OR&lt;/code&gt; is used.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&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;UserMembershipQuery&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;members&lt;/span&gt;
    &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;public_profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group_member&lt;/span&gt;&lt;span class="p"&gt;))&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;table&lt;/span&gt;
    &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arel_table&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;public_profile&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:private&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&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;group_member&lt;/span&gt;
    &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:group_member&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;users&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;in&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;2&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="nf"&gt;to_sql&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"`users`.`id` IN (1, 2, 3)"&lt;/span&gt;

&lt;span class="n"&gt;users&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;gt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_sql&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"`users`.`id` &amp;gt; 2"&lt;/span&gt;

&lt;span class="n"&gt;users&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;eq&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="nf"&gt;to_sql&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"`users`.`id` = 3"&lt;/span&gt;

&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&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;in&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;2&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="nf"&gt;to_sql&lt;/span&gt;
&lt;span class="c1"&gt;# SELECT "users".* FROM "users"  WHERE "users"."id" IN (1, 2, 3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  - Projection queries
&lt;/h4&gt;

&lt;p&gt;Projection queries are the same as the &lt;code&gt;select&lt;/code&gt; queries, we use the &lt;code&gt;project&lt;/code&gt; to specify the nodes we want to select or return. This would need to be executed directly as SQL and can not easily be combined with ActiveRecord queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:role&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_sql&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"SELECT email FROM `users` WHERE `users`.`role` = 2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to connect these queries with the Active Record is a little bit more complex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&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;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec_query&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:role&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  - Joins
&lt;/h4&gt;

&lt;p&gt;Here where we can see that Arel is really useful, cause writing join queries using Arel is a lot more simple and readable than SQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arel_table&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes! It's that simple! We can also determine the relationship&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Arel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Nodes&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;OuterJoin&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&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;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_id&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to write join with a condition&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:subscriptions&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;active: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;There are other methods that we can use to scope different queries:&lt;br&gt;
Like &lt;code&gt;sum&lt;/code&gt;, &lt;code&gt;average&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;, and &lt;code&gt;max&lt;/code&gt; that we can use to perform different operations on values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:rate&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;average&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we slightly discussed the basics of Arel like what's it and its history and its basic syntax but it has a lot more stuff that could be very helpful on, and there's a lot more to learn about it, so, I recommend you to go through &lt;a href="https://www.rubydoc.info/gems/arel#description"&gt;Arel documentation&lt;/a&gt; and get your hand dirty and start using it.&lt;br&gt;
If u have any comments or any feedback I will be happy to hear from your side.&lt;/p&gt;

&lt;p&gt;Reviewed by &lt;strong&gt;&lt;em&gt;Farha Zane&lt;/em&gt;&lt;/strong&gt; ❤︎&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>sql</category>
      <category>database</category>
    </item>
    <item>
      <title>Adding Markdown to your Rails application</title>
      <dc:creator>Abd ElRahman Shawareb</dc:creator>
      <pubDate>Tue, 08 Jun 2021 15:33:10 +0000</pubDate>
      <link>https://dev.to/ashawareb/adding-markdown-to-your-rails-application-p73</link>
      <guid>https://dev.to/ashawareb/adding-markdown-to-your-rails-application-p73</guid>
      <description>&lt;p&gt;In this guide I will show you how to add markdown to your rails application. We will use &lt;a href="https://github.com/vmg/redcarpet"&gt;redcarpet&lt;/a&gt; gem and I assume that you have created your rails application that we will work on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install redcarpet
&lt;/h2&gt;

&lt;p&gt;To install redcarpet gem go to your &lt;strong&gt;Gemfile&lt;/strong&gt; and add:&lt;br&gt;
&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;# Gemfile &lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"redcarpet"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generating a resource
&lt;/h2&gt;

&lt;p&gt;After we successfully installed our gem, we need a recourse to work with and test our work, so we will create Post scaffold to work with.&lt;/p&gt;

&lt;p&gt;To create the Post scaffold run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails generate scaffold Post title:string body:text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extracting logic to a helper
&lt;/h2&gt;

&lt;p&gt;After we successfully installed redcarpet gem and created our scaffold it's the time to add markdown to our application.&lt;/p&gt;

&lt;p&gt;In order to be DRY (don't repeat yourself) we will create a helper method to use whenever we want to add markdown. So in our &lt;code&gt;application_helper.rb&lt;/code&gt; we will add the following code:&lt;br&gt;
&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;def&lt;/span&gt; &lt;span class="nf"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%i[
      hard_wrap autolink no_intra_emphasis tables fenced_code_blocks
      disable_indented_code_blocks strikethrough lax_spacing space_after_headers
      quote footnotes highlight underline
    ]&lt;/span&gt;
    &lt;span class="no"&gt;Markdown&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;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;html_safe&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method titled &lt;code&gt;markdown&lt;/code&gt; will take a text as an argument and will be the output of Post &lt;code&gt;body&lt;/code&gt; field. Notice the &lt;code&gt;options&lt;/code&gt; variable defined with an array of settings you can pass to Redcarpet. These dictate what you do and don't want when it comes to rendering markdown within your app.&lt;/p&gt;

&lt;p&gt;Now let's use this helper in our views&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"notice"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= notice %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Title:&amp;lt;/strong&amp;gt;
  &amp;lt;%=&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;title&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;
&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;strong&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Body&lt;/span&gt;&lt;span class="ss"&gt;:&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;strong&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= markdown(@post.body) %&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s1"&gt;'Edit'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edit_post_path&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="o"&gt;%&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to 'Back', posts_path %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And congratulation you have added markdown to your application.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>markdown</category>
      <category>ruby</category>
      <category>webdev</category>
    </item>
    <item>
      <title>1. Introduction to Design Patterns</title>
      <dc:creator>Abd ElRahman Shawareb</dc:creator>
      <pubDate>Sat, 20 Mar 2021 14:26:43 +0000</pubDate>
      <link>https://dev.to/ashawareb/1-introduction-to-design-patterns-1mmm</link>
      <guid>https://dev.to/ashawareb/1-introduction-to-design-patterns-1mmm</guid>
      <description>&lt;p&gt;Hi everyone, it is the first article of my Design Patterns series. In this series, we will understand almost everything related to Design Patterns. So let's start with an introduction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In Software Engineering you may face the same design problems again and again and of course, there are many ways to solve these problems, but to avoid more problems in the future when you try to maintain your code, we need to use flexible and reusable solutions. One of these preferred solutions is that of &lt;strong&gt;design patterns&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Design Pattern?
&lt;/h2&gt;

&lt;p&gt;A design pattern is a practical proven solution to a common design problem. It is like the best practices used by expert software engineers to solve this problem and these solutions help us to speed the process of development because you don't have to think, create and build a solution every time you face these problems. Also, a design pattern is not a standard piece of code that you just put in your code and the problem is solved, it is more like a model that you can modify to be suitable to use in your problem. &lt;/p&gt;

&lt;h2&gt;
  
  
  Gang of Four (GoF)
&lt;/h2&gt;

&lt;p&gt;Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides are the authors of the famous book &lt;strong&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/strong&gt;. They introduced 23 patterns of design in this book based on their experience as developers. Those patterns -which were introduced by GoF- are considered the foundation for all other patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Categories of Design Patterns
&lt;/h2&gt;

&lt;p&gt;Gang of Four patterns can be categorized into three groups:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Creational Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Creational Patterns&lt;/strong&gt; help us to deal with creating or cloning new objects. &lt;strong&gt;Creational Patterns&lt;/strong&gt; are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Factory Method&lt;/li&gt;
&lt;li&gt;Abstract Factory&lt;/li&gt;
&lt;li&gt;Builder&lt;/li&gt;
&lt;li&gt;Singleton&lt;/li&gt;
&lt;li&gt;Object Pool&lt;/li&gt;
&lt;li&gt;Prototype&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Structural Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Structural Patterns&lt;/strong&gt; help us to describe the connections between objects. These patterns relate to design principles of &lt;strong&gt;decomposition&lt;/strong&gt; and &lt;strong&gt;generalization&lt;/strong&gt;. &lt;strong&gt;Structural Patterns&lt;/strong&gt; are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adapter &lt;/li&gt;
&lt;li&gt;Bridge &lt;/li&gt;
&lt;li&gt;Composite &lt;/li&gt;
&lt;li&gt;Decorator &lt;/li&gt;
&lt;li&gt;Facade &lt;/li&gt;
&lt;li&gt;Flyweight &lt;/li&gt;
&lt;li&gt;Private Class Data &lt;/li&gt;
&lt;li&gt;Proxy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Behavioral Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Behavioral Patterns&lt;/strong&gt; help us to describe how each object performs a single cohesive function and describe how independent objects work towards a common goal. &lt;strong&gt;Behavioral Patterns&lt;/strong&gt; are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chain of Responsibility &lt;/li&gt;
&lt;li&gt;Command &lt;/li&gt;
&lt;li&gt;Interpreter &lt;/li&gt;
&lt;li&gt;Iterator &lt;/li&gt;
&lt;li&gt;Mediator &lt;/li&gt;
&lt;li&gt;Memento &lt;/li&gt;
&lt;li&gt;Null Object &lt;/li&gt;
&lt;li&gt;Observer &lt;/li&gt;
&lt;li&gt;State &lt;/li&gt;
&lt;li&gt;Strategy &lt;/li&gt;
&lt;li&gt;Template method &lt;/li&gt;
&lt;li&gt;Visitor &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Elements of a Design Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Gang of Four's&lt;/strong&gt; book tells us that each pattern has four essential elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Name&lt;/strong&gt; - Used to describe a design problem, its solutions, and consequences in a word or two.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Problem&lt;/strong&gt; - describes when to apply the pattern and explains the problem and its context. &lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Solution&lt;/strong&gt; - that describes the elements that make up the design, the relationships, the responsibilities, and collaborations. The solutions do not describe a concrete implementation, because a pattern is like a template that can be applied in many different situations, but provides an abstract description of a design problem and how a general arrangement of elements (classes and objects) solves it.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;consequences&lt;/strong&gt; - the results of applying the pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reasons to use Design Patterns
&lt;/h2&gt;

&lt;p&gt;There are many reasons to use design patterns. As we said before it makes the process of implementation faster because we don't have to think and build a solution for a problem every time we face it. It also defines a common language to make it easier to communicate between team members.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we give a quick introduction to design patterns and discussed categories of design patterns, elements of each pattern, and why we should use design patterns. In the following articles, we will talk in detail about each pattern and how to use design patterns.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>designpatterns</category>
      <category>architecture</category>
    </item>
    <item>
      <title>SOLID Principles: For maintainable, flexible, and extensible code</title>
      <dc:creator>Abd ElRahman Shawareb</dc:creator>
      <pubDate>Tue, 09 Feb 2021 04:50:40 +0000</pubDate>
      <link>https://dev.to/ashawareb/solid-principles-for-maintainable-flexible-and-extensible-code-4p0c</link>
      <guid>https://dev.to/ashawareb/solid-principles-for-maintainable-flexible-and-extensible-code-4p0c</guid>
      <description>&lt;p&gt;Hi everyone, in this article, we will talk about &lt;strong&gt;SOLID&lt;/strong&gt; principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;SOLID&lt;/strong&gt; principles were introduced by Robert C. Martin (Uncle Bob). The intention of these principles is to help us write maintainable, flexible, and extensible code. and by applying these principles in our design we can also avoid code smells and refactor our code.&lt;/p&gt;

&lt;h2&gt;
  
  
  SOLD Stands for:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt; - Single-responsiblity Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt; - Open-closed Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt; - Liskov Substitution Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt; - Interface Segregation Principle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt; - Dependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples will be given in Ruby, but these principles can be applied to any OOP language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single-responsibility Principle (SRP)
&lt;/h2&gt;

&lt;p&gt;Single-responsibility Principle (SRP) states that &lt;strong&gt;"A class should have only a single responsibility."&lt;/strong&gt;&lt;br&gt;
let's simplify this definition together, What does &lt;strong&gt;single responsibility&lt;/strong&gt; mean? simply it means that our class should only have one reason to change and will happen if our class only has one job. &lt;/p&gt;

&lt;p&gt;The concept behind (SRP) sounds simple and clear but to apply this principle in your design you have to spend some time since a class’s responsibility isn’t always clear.&lt;/p&gt;

&lt;p&gt;The following example of code does not follow the SRP&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc1czlim3oifyg67u0ex3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc1czlim3oifyg67u0ex3.png" alt="SRP Bad Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FinancialReportMailer handles two tasks (generate_report!) and (send_report) as shown above, So why this class does not apply the SRP principle? let's answer this question by asking one more question, What is the main responsibility of this class? is it to generate the financial report or send it? So according to this principle, we should divide the FinancialReportMailer class into two classes.&lt;/p&gt;

&lt;p&gt;Now let's refactor our class and apply SRP&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbs0tsg7f5xb8k0roj8g4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbs0tsg7f5xb8k0roj8g4.png" alt="SRP Good Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After refactoring, we have two classes that each perform exactly one task. So if we wanted to expand the class responsible for report generation in the future, we could simply make the necessary changes without having to touch the FinancialReportMailer class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open-closed Principle (OCP)
&lt;/h2&gt;

&lt;p&gt;Open-closed Principle (OCP) states that &lt;strong&gt;"Objects or entities should be open for extension but closed for modification"&lt;/strong&gt;&lt;br&gt;
That means we need to design our classes to be extendable without modifying the class itself.&lt;/p&gt;

&lt;p&gt;This principle is important to follow to design a system that is easy to modify and extend in the future&lt;/p&gt;

&lt;p&gt;Now let's take an example that does not follow the OCP.&lt;/p&gt;

&lt;p&gt;The Logger class formats and sends logs. But the OCP principle is not followed, since we will have to modify the logger every time we need to add additional senders or formatters:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fghp2wcjrquzpb2ii7h2j.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fghp2wcjrquzpb2ii7h2j.png" alt="OCP Bad Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's refactor this code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4s0xgddsos0vbhudrwf2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4s0xgddsos0vbhudrwf2.png" alt="OCP Good Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example above, we have segregated senders and formatters to separate classes and enabled the addition of new senders and formatters without having to modify the base code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Liskov Substitution Principle (LSP)
&lt;/h2&gt;

&lt;p&gt;Liskov Substitution Principle (LSP) states that &lt;strong&gt;"If S is a subtype of T, then objects of type T may be replaced with objects of type S"&lt;/strong&gt; &lt;br&gt;
It sounds confusing, but do not worry, we will simplify it together. Let's break down the definition into small manageable pieces, from the definition of the principle we know that we are going to be working with parent and child classes, this tells us that the principle revolves around the object-oriented inheritance. Also from the definition, it sounds like programs have to be able to allow for child classes to seamlessly replace parent classes, and to make this happen we should ensure that our parent and child classes cannot have requirements that would cause conflicts.&lt;/p&gt;

&lt;p&gt;Now that we know what the LSP principle is getting at, let's look at an example that violates LSP.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa7xm0jw264g70if7xd16.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa7xm0jw264g70if7xd16.png" alt="LSP Bad Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example above, we are implementing user statistics. There are two classes: a base class (UserStatistic) and its child class (AdminStatistic). The child class violates the LSP principle since it completely redefines the base class by returning a string with filtered data, whereas the base class returns an array of posts.&lt;/p&gt;

&lt;p&gt;Now let's refactor this code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foqkxk8tsfx82zkg37hq7.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foqkxk8tsfx82zkg37hq7.png" alt="LSP Good Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To apply LSP, we can segregate the filtration logic and the statistics string generation logic into two methods: “posts“ and “formatted_posts“. Therefore, we refactored the method posts that filtrate user posts, so the method returns the same type of data as the base class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interface Segregation Principle (ISP)
&lt;/h2&gt;

&lt;p&gt;Interface Segregation Principle states that &lt;strong&gt;"Clients should not be forced to depend upon interfaces that they don't use."&lt;/strong&gt;&lt;br&gt;
More simply: Do not add additional functionality to an existing interface by adding new methods. we should get the interfaces segregated according to their purpose, so we avoid “fat” classes and code that’s hard to maintain. In our design, we should not force our classes to implement unneeded methods (Dummy implementation).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Several client-specific interfaces are better than one generalized interface."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's take an example that does not apply ISP.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgh1rdul9ramczy8sdq5l.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgh1rdul9ramczy8sdq5l.png" alt="ISP Bad Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example above, we have a piece of code that represents a coffee vending machine interface. As you can see, the interface is used by two types of users: a Person and a Staff. Each uses only a few interface abilities, however. For example, the class Person uses only the following methods: “select_drink_type“, “select_portion“, “select_sugar_amount“, and “brew_coffee“. The ISP principle tells that one class should contain only the method it uses.&lt;/p&gt;

&lt;p&gt;To refactor this code, we created two interfaces: a separate user interface and a separate staff interface. In the “CoffeeMachineUserInterface,” a user will be able to choose a drink type (method “select_drink_type“), choose a portion size (method “select_portion“), select the amount of sugar they would like added to the drink (method “select_sugar_amount“), and start brewing the coffee (method “brew_coffee“). A staff member, using the “CoffeeMachineSeviceInterface,” will be able to choose among the following operations: clean the machine (method “clean_coffee_machine“), fill sugar (method “fill_sugar_supply“), fill coffee beans (method “fill_coffee_beans“), and fill water supply (method “fill_water_supply“).&lt;/p&gt;

&lt;p&gt;With this design segregated in two interfaces, we’ve avoided unused methods and now have two smaller interfaces with methods that perform specific tasks.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqnn9n51wgxiz077u1zav.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqnn9n51wgxiz077u1zav.png" alt="ISP Good Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency Inversion Principle (DIP)
&lt;/h2&gt;

&lt;p&gt;Dependency Inversion Principle states that &lt;strong&gt;"High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions."&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High-level modules&lt;/strong&gt; = &lt;strong&gt;interfaces&lt;/strong&gt; and &lt;strong&gt;abstract classes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low-level&lt;/strong&gt; = &lt;strong&gt;concrete classes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uncle Bob claims that the DIP principle is simply the result of strictly following the LSP and OCP. According to Uncle Bob, the code that follows the LSP and OCP should also be extendable, and child classes should be easily replaceable by other instances of a base class without breaking the system. &lt;/p&gt;

&lt;p&gt;By using DIP we will be able to increase the reusability of higher-level modules by making them independent of lower-level modules.&lt;/p&gt;

&lt;p&gt;In the code below, we have implemented logic for a printer (the Printer class has the method print which performs data output). &lt;/p&gt;

&lt;p&gt;The class Printer depends on classes PdfFormatter and HtmlFormatter instead of abstractions, which indicates the violation of the DIP principle since the classes PdfFormatter and HtmlFormatter may contain the logic that refers to other classes. Thus, we may impact all the related classes when modifying the class Printer.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F23si537mb75so8yj5g9d.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F23si537mb75so8yj5g9d.png" alt="DIP Bad Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's refactor the code above and apply DIP. Implementation of low-level details (outputting formats like PDF and HTML) is done in separate classes (PDF Formatter and HTML Formatter).&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F91dj6pfbv1lm9lvcbibs.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F91dj6pfbv1lm9lvcbibs.png" alt="DIP Good Examole"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the code above, the printer ‒ a high-level object ‒ doesn’t depend directly on the implementation of low-level objects ‒ the PDF and HTML formatters. In addition, all modules depend on abstraction. Our high-level functionality is separated from all low-level details, so we’re able to easily change the low-level logic without system-wide implications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we discussed the 5 SOLID principles, the benefits of using these principles, and we tried to understand each principle and refactored some examples in each one of the principles.&lt;/p&gt;

&lt;p&gt;I wish this article was helpful for you, and thanks for taking the time to read the whole article. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>ood</category>
      <category>beginners</category>
      <category>solid</category>
    </item>
  </channel>
</rss>
