<?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: rockshellS</title>
    <description>The latest articles on DEV Community by rockshellS (@rockshells).</description>
    <link>https://dev.to/rockshells</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%2F552536%2F1d3857ab-64cb-40ce-8868-05c6ec16f7b0.jpg</url>
      <title>DEV Community: rockshellS</title>
      <link>https://dev.to/rockshells</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rockshells"/>
    <language>en</language>
    <item>
      <title>What the Fetch?</title>
      <dc:creator>rockshellS</dc:creator>
      <pubDate>Tue, 16 Mar 2021 15:30:35 +0000</pubDate>
      <link>https://dev.to/rockshells/what-the-fetch-2n5e</link>
      <guid>https://dev.to/rockshells/what-the-fetch-2n5e</guid>
      <description>&lt;p&gt;what is fetch()&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch('https://api.punkapi.com/v2/beers')
  .then(response =&amp;gt; response.json())
  .then(beers =&amp;gt; console.log(beers));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the above is a basic fetch request. it's a function in JavaScript for interacting with a database. Let me break down this code some and get a better understanding on what's going on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch('https://api.punkapi.com/v2/beers')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;fetch() can take in two arguments. one mandatory argument, the URL of the resource you're looking for data from. This is the GET request. Just getting the info from the API. We will talk about the second argument a little later.  Let's take a look and this first line of code. Open up your DevTools and copy paste the line above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch('https://api.punkapi.com/v2/beers')
Promise {&amp;lt;pending&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Promise { pending } ?  what is this? I was told that a promise is like an IOU. At some point you will be getting a response. It doesn't mean the response is what you are wanting. The response could be an error. They can be fulfilled, rejected or pending.&lt;/p&gt;

&lt;p&gt;Let's take a look and the second line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.then(resp =&amp;gt; resp.json())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the fetch returns it's promise with this function that has the response you requested from the API and it's putting it into json format. &lt;br&gt;
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. -&lt;a href="http://www.json.org" rel="noopener noreferrer"&gt;www.json.org&lt;/a&gt;&lt;br&gt;
we can see that the promise was fulfilled and now we have some data. An Array(25)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Promise {&amp;lt;pending&amp;gt;}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(25)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the third line of code is where you finally get to use  and do things with the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.then(beers =&amp;gt; console.log(beers));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let's take a look. Put the code in DevTools and what do we get?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch('https://api.punkapi.com/v2/beers')
  .then(response =&amp;gt; response.json())
  .then(beers =&amp;gt; console.log(beers));
Promise {&amp;lt;pending&amp;gt;}
base.js:8238 
(25) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: 1, name: "Buzz", tagline: "A Real Bitter Experience.", first_brewed: "09/2007", description: "A light, crisp and bitter IPA brewed with English and American hops. A small batch brewed only once.", …}
1: {id: 2, name: "Trashy Blonde", tagline: "You Know You Shouldn't", first_brewed: "04/2008", description: "A titillating, neurotic, peroxide punk of a Pale A…the customary BrewDog bite and imaginative twist.", …}
2: {id: 3, name: "Berliner Weisse With Yuzu - B-Sides", tagline: "Japanese Citrus Berliner Weisse.", first_brewed: "11/2015", description: "Japanese citrus fruit intensifies the sour nature of this German classic.", …}
3: {id: 4, name: "Pilsen Lager", tagline: "Unleash the Yeast Series.", first_brewed: "09/2013", description: "Our Unleash the Yeast series was an epic experimen…nols, although it can add a hint of butterscotch.", …}
4: {id: 5, name: "Avery Brown Dredge", tagline: "Bloggers' Imperial Pilsner.", first_brewed: "02/2011", description: "An Imperial Pilsner in collaboration with beer wri…hat rock our world, and the people who make them.", …}
5: {id: 6, name: "Electric India", tagline: "Vibrant Hoppy Saison.", first_brewed: "05/2013", description: "Re-brewed as a spring seasonal, this beer – which …re also added to produce a genuinely unique beer.", …}
6: {id: 7, name: "AB:12", tagline: "Imperial Black Belgian Ale.", first_brewed: "07/2012", description: "An Imperial Black Belgian Ale aged in old Invergor…yberries and blackberries beause they were local.", …}
7: {id: 8, name: "Fake Lager", tagline: "Bohemian Pilsner.", first_brewed: "03/2013", description: "Fake is the new black. Fake is where it is at. Fak…y faux masterpiece with added BrewDog bitterness.", …}
8: {id: 9, name: "AB:07", tagline: "Whisky Cask-Aged Scotch Ale.", first_brewed: "03/2010", description: "Whisky cask-aged imperial scotch ale. Beer perfect… beer capable of holding back the Scottish chill.", …}
9: {id: 10, name: "Bramling X", tagline: "Single Hop IPA Series - 2011.", first_brewed: "01/2011", description: "Good old Bramling Cross is elegant, refined, assur…apple and ginger jam my grandmother used to make.", …}
10: {id: 11, name: "Misspent Youth", tagline: "Milk &amp;amp; Honey Scotch Ale.", first_brewed: "04/2013", description: "The brainchild of our small batch brewer, George W…erously drinkable milk sugar- infused Scotch Ale.", …}
11: {id: 12, name: "Arcade Nation", tagline: "Seasonal Black IPA.", first_brewed: "12/2015", description: "Running the knife-edge between an India Pale Ale a…ryness from the malt bill at each and every turn.", …}
12: {id: 13, name: "Movember", tagline: "Moustache-Worthy Beer.", first_brewed: "11/2009", description: "A deliciously robust, black malted beer with a dec…rovides an enticing backdrop to the Cascade hops.", …}
13: {id: 14, name: "Alpha Dog", tagline: "Existential Red Ale.", first_brewed: "02/2010", description: "A fusion of caramel malt flavours and punchy New Z…hops. A session beer you can get your teeth into.", …}
14: {id: 15, name: "Mixtape 8", tagline: "An Epic Fusion Of Old Belgian, American New Wave, And Scotch Whisky.", first_brewed: "01/2012", description: "This recipe is for the Belgian Tripel base. A blen…, fruity esters, and punchy citrus hop character.", …}
15: {id: 16, name: "Libertine Porter", tagline: "Dry-Hopped Aggressive Porter.", first_brewed: "01/2012", description: "An avalanche of cross-continental hop varieties gi… toffee, bitter chocolate and hints of woodsmoke.", …}
16: {id: 17, name: "AB:06", tagline: "Imperial Black IPA.", first_brewed: "04/2011", description: "Our sixth Abstrakt, this imperial black IPA combin…our favourite American hops. Roasty and resinous.", …}
17: {id: 18, name: "Russian Doll – India Pale Ale", tagline: "Nesting Hop Bomb.", first_brewed: "08/2014", description: "The levels of hops vary throughout the range. We l… and yet still lends different characters to each", …}
18: {id: 19, name: "Hello My Name Is Mette-Marit", tagline: "Lingonberry Double IPA.", first_brewed: "06/2013", description: "We sent this beer to Norway where it was known as …nous bitter edge layered with dry berry tartness.", …}
19: {id: 20, name: "Rabiator", tagline: "Imperial Wheat Beer", first_brewed: "03/2011", description: "Imperial Wheat beer / Weizenbock brewed by a homes…nk banana bread, bubble gum and David Hasselhoff.", …}
20: {id: 21, name: "Vice Bier", tagline: "Hoppy Wheat Bier.", first_brewed: "04/2013", description: "Our take on the classic German Kristallweizen. A c… balanced with the American and New Zealand hops.", …}
21: {id: 22, name: "Devine Rebel (w/ Mikkeller)", tagline: "Oak-aged Barley Wine.", first_brewed: "12/2008", description: "Two of Europe's most experimental, boundary-pushin… and was going to be partially aged in oak casks.", …}
22: {id: 23, name: "Storm", tagline: "Islay Whisky Aged IPA.", first_brewed: "12/2007", description: "Dark and powerful Islay magic infuses this tropica…to the peated smoke imported directly from Islay.", …}
23: {id: 24, name: "The End Of History", tagline: "The World's Strongest Beer.", first_brewed: "06/2011", description: "The End of History: The name derives from the famo…caramel and cloves are intensified by boozy heat.", …}
24: {id: 25, name: "Bad Pixie", tagline: "Spiced Wheat Beer.", first_brewed: "10/2008", description: "2008 Prototype beer, a 4.7% wheat ale with crushed juniper berries and citrus peel.", …}
length: 25
__proto__: Array(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get excited cuz now you can work with this data!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch('https://api.punkapi.com/v2/beers')
  .then(response =&amp;gt; response.json())
  .then(beers =&amp;gt; console.log(beers[5].name));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What beer does this return?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5: {id: 6, name: "Electric India", tagline: "Vibrant Hoppy Saison.", first_brewed: "05/2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's talk about that second optional argument. We could request to do a few things here with the API&lt;/p&gt;

&lt;p&gt;POST - is requesting to add data &lt;/p&gt;

&lt;p&gt;PATCH - is requesting to edit the data&lt;/p&gt;

&lt;p&gt;DELETE - is requesting to delete some data&lt;/p&gt;

&lt;p&gt;the second argument will be a JavaScript object which will have information that will communicate to the backend and the application. One way to set a POST is like this. The reqObj will have three key-value pairs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let reqObj = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
},

  body: JSON.stringify({
    name:,
    tagline:

})
};

fetch('https://api.punkapi.com/v2/beers, reqObj)
.then(resp =&amp;gt; resp.json())
.then(beer =&amp;gt; {
console.log(beer)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down those key-value pairs.&lt;br&gt;
method: 'POST' - this is the request we are sending to the backend.&lt;br&gt;
headers: &lt;br&gt;
   Content-Type is the type of data content we are sending&lt;br&gt;
   Accept is the data content we will take in return&lt;br&gt;
body: is data this is in string format.&lt;/p&gt;

&lt;p&gt;The way we would set up Patch is like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch(`https://api.punkapi.com/v2/beers/${beerId}`,{
  method: 'PATCH',
  headers: {
   'Content-Type':'application/json'
},
  body: JSON.stringify({
   "new updates"
})
})
.then(resp =&amp;gt; resp.json())
.then(beer =&amp;gt; {
console.log(beer)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTICE we used bac-tics with this fetch. We want to edit individual beers and to do that we need to specifically use the beerId. So we interpolate the beeId into the URL.&lt;/p&gt;

&lt;p&gt;Now with deleting a beer it's much less code. We still need the beerId and we only need the method. like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch(`'https://api.punkapi.com/v2/beers/${beerId}`,{ 
  method: 'DELETE' 
})
.then(resp =&amp;gt; resp.json())
.then(beer =&amp;gt; {
console.log(beer)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F7nn8s1zx7lt1nab0x10b.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7nn8s1zx7lt1nab0x10b.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this was helpful and to look at some free API's check out &lt;a href="https://github.com/public-apis/public-apis" rel="noopener noreferrer"&gt;https://github.com/public-apis/public-apis&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Callbacks are calling...</title>
      <dc:creator>rockshellS</dc:creator>
      <pubDate>Tue, 16 Mar 2021 15:30:24 +0000</pubDate>
      <link>https://dev.to/rockshells/callbacks-are-calling-3p6n</link>
      <guid>https://dev.to/rockshells/callbacks-are-calling-3p6n</guid>
      <description>&lt;p&gt;Writing my second blog for Flatiron has taken me down some worm holes. Which hasn't been a bad thing! While learning Ruby on Rails we came across Validations, and how/when to use them. Validations are used to ensure that only valid data is saved into your database. Seems like a secure way to handle information. A Callback is called before or after the Validation is called. These actions happen fast and are considered magic.&lt;/p&gt;

&lt;p&gt;-Callbacks are methods that get called at certain moments of an object’s life cycle. With them is possible to write code that will run whenever an ActiveRecord object is created, saved, updated, deleted, validated or loaded from the database - Ruby on Rails Guide&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%2F2xutite9iapjd45ggoxf.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2xutite9iapjd45ggoxf.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In rails c,&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;run&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;Callbacks&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CALLBACKS&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:after_initialize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_find&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_touch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="ss"&gt;:before_validation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_validation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:before_save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="ss"&gt;:around_save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:before_create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:around_create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="ss"&gt;:after_create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:before_update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:around_update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="ss"&gt;:before_destroy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:around_destroy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_destroy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="ss"&gt;:after_commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:after_rollback&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this is a list of available callbacks. &lt;/p&gt;

&lt;p&gt;In order to use callbacks, you need to register them. Which means you need to add them to your Model using the correct method. You can do this four different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Method references (symbol)- recommended&lt;/li&gt;
&lt;li&gt;Callback objects -recommended&lt;/li&gt;
&lt;li&gt;Inline methods (using a proc)-when appropriate&lt;/li&gt;
&lt;li&gt;Inline evals methods (using a string)-deprecated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some examples on how to use them. These code examples are from the ActiveRecords guide page&lt;br&gt;
&lt;a href="http://guides.rubyonrails.org/active_record_callbacks.html" rel="noopener noreferrer"&gt;http://guides.rubyonrails.org/active_record_callbacks.html&lt;/a&gt;&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:login&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="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;

  &lt;span class="n"&gt;before_validation&lt;/span&gt; &lt;span class="ss"&gt;:ensure_login_has_a_value&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;ensure_login_has_a_value&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&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;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This callback before_validation is making sure that the user has a valid login before it will run the validates method.  By calling the ensure_login_has_a_value method wrote in the private section in the User class.  Everything happens here in the model. &lt;/p&gt;

&lt;p&gt;You can pass blocks ( useful for short one-liner logic )&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:login&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="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;

  &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&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;Callbacks can also be registered to only fire on certain life cycle events:&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
          &lt;span class="n"&gt;before_validation&lt;/span&gt; &lt;span class="ss"&gt;:normalize_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;on: :create&lt;/span&gt;

        &lt;span class="c1"&gt;# :on takes an array as well&lt;/span&gt;
          &lt;span class="n"&gt;after_validation&lt;/span&gt; &lt;span class="ss"&gt;:set_location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;on: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
          &lt;span class="ss"&gt;:update&lt;/span&gt; &lt;span class="p"&gt;]&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;normalize_name&lt;/span&gt;
           &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;titleize&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;set_location&lt;/span&gt;
           &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;LocationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&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;Here before_validation is calling the normalize_name method on: :create. Which will make sure the User name is in downcase and titlized. The after_validation is calling the set_location method on: [ :create, :update ] &lt;/p&gt;

&lt;p&gt;Relational Callbacks:&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
        &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;dependent: :destroy&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
        &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="ss"&gt;:log_destroy_action&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_destroy_action&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Article destroyed'&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;user&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;first&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;User id: 1&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Article id: 1, user_id: 1&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;
&lt;span class="no"&gt;Article&lt;/span&gt; &lt;span class="n"&gt;destroyed&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;User id: 1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the user has many accounts and when they delete their account all their articles should be deleted as well by using dependent: :destroy.&lt;/p&gt;

&lt;p&gt;Another example of registering callbacks with callback macros is that they are inheritable&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;class&lt;/span&gt; &lt;span class="nc"&gt;Sweet&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
       &lt;span class="n"&gt;before_save&lt;/span&gt; &lt;span class="ss"&gt;:do_something_with_sweet&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vendor&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
       &lt;span class="n"&gt;before_save&lt;/span&gt; &lt;span class="ss"&gt;:do_something_with_vendor&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here when the save method is call on Vendor instance, both :do_something_with_sweet and :do_something_with_vendor are triggered.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
     &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="ss"&gt;:send_email_to_author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;if: 
      :author_wants_emails?&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="ss"&gt;unless: &lt;/span&gt;&lt;span class="no"&gt;Proc&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="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 
       &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ignore_comments?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the after_create will send_email_to_author if author_wants_emails.&lt;br&gt;
unless (Proc is looping thorough all the comments) and the people who had comments wouldn't get an email.&lt;/p&gt;

&lt;p&gt;It’s possible to skip callbacks with these methods: &lt;a href="http://guides.rubyonrails.org/active_record_callbacks.html" rel="noopener noreferrer"&gt;http://guides.rubyonrails.org/active_record_callbacks.html&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;decrement!&lt;/li&gt;
&lt;li&gt;decrement_counter&lt;/li&gt;
&lt;li&gt;delete&lt;/li&gt;
&lt;li&gt;delete_all&lt;/li&gt;
&lt;li&gt;delete_by&lt;/li&gt;
&lt;li&gt;increment!&lt;/li&gt;
&lt;li&gt;increment_counter&lt;/li&gt;
&lt;li&gt;insert&lt;/li&gt;
&lt;li&gt;insert!&lt;/li&gt;
&lt;li&gt;insert_all&lt;/li&gt;
&lt;li&gt;insert_all!&lt;/li&gt;
&lt;li&gt;touch_all&lt;/li&gt;
&lt;li&gt;update_column&lt;/li&gt;
&lt;li&gt;update_columns&lt;/li&gt;
&lt;li&gt;update_all&lt;/li&gt;
&lt;li&gt;update_counters&lt;/li&gt;
&lt;li&gt;upsert&lt;/li&gt;
&lt;li&gt;upsert_all&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foqgxdztqu0c7f3sq24b5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foqgxdztqu0c7f3sq24b5.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusion, There are so many different fun ways for Callbacks to be used. They are magical and should be used sparingly. Using too many could become a problem and hard to navigate. I hope this was helpful.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ruby Spaceship</title>
      <dc:creator>rockshellS</dc:creator>
      <pubDate>Tue, 16 Mar 2021 15:30:06 +0000</pubDate>
      <link>https://dev.to/rockshells/ruby-spaceship-7bp</link>
      <guid>https://dev.to/rockshells/ruby-spaceship-7bp</guid>
      <description>&lt;p&gt;Hey everyone. Welcome to my first ever blog post. The past 20 years I have been working in the music industry putting together live events as a production manager. I'm not going to lie, it's been a wild and crazy ride. Covid-19 hit my career pretty hard, with no comeback in sight, so I've decided to challenge myself and learn some software engineering skills.  Here at FlatIron, information is dealt out on such a fast pace, yet I can tell I'm learning a few things! Definitely challenging, but so damn exciting when I can get something to work!&lt;br&gt;
  Before I joined my cohort I was watching a ton of YouTube videos about Ruby. This is when the spaceship operator, (combined comparison operator), showed up. I realized after watching him that all the information I was taking in, particularly Ruby,  was starting to register and make sense!   LOL, the word "spaceship". see this symbol &amp;lt;=&amp;gt; looks similar to &lt;br&gt;
this....&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5nnRJ3ol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nwrh9w4orchd823hmfji.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5nnRJ3ol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nwrh9w4orchd823hmfji.jpg" alt="download"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, let's see the tech stuff.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wl4sGrzR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/28s76hxhmu92kw6v3xxk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wl4sGrzR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/28s76hxhmu92kw6v3xxk.jpg" alt="CpwOf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the spaceship operator compares two objects:&lt;/p&gt;

&lt;p&gt;1 &amp;lt;=&amp;gt; 1 #=&amp;gt; 0 because the two objects are equal&lt;br&gt;
1 &amp;lt;=&amp;gt; 2 #=&amp;gt; -1 because the second object's value is larger&lt;br&gt;
2 &amp;lt;=&amp;gt; 1 #=&amp;gt; 1 because the first object's value is larger&lt;br&gt;
2 &amp;lt;=&amp;gt; "nope" #=&amp;gt; nil if either object is not comparable then the spaceship operator &lt;/p&gt;

&lt;p&gt;another example:&lt;/p&gt;

&lt;p&gt;100 &amp;lt;=&amp;gt; 100 #=&amp;gt; 0&lt;br&gt;
-55 &amp;lt;=&amp;gt; 256 #=&amp;gt; -1&lt;br&gt;
999 &amp;lt;=&amp;gt; 23 #=&amp;gt; 1&lt;br&gt;
-100 &amp;lt;=&amp;gt; "not again" #=&amp;gt; nil&lt;/p&gt;

&lt;p&gt;I watched a great example by Jesus Castello on how to use this operator. I'll show you his code...&lt;/p&gt;

&lt;p&gt;numbers = array (1..10)&lt;br&gt;
 =&amp;gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] &lt;/p&gt;

&lt;p&gt;target = 5&lt;br&gt;
 =&amp;gt; 5 &lt;/p&gt;

&lt;p&gt;Jesus suggests we could find all the numbers less than the target and find all the numbers greater than the target by writing this code.&lt;/p&gt;

&lt;p&gt;less_than =[]&lt;br&gt;
greater_than = []&lt;/p&gt;

&lt;p&gt;numbers.each do |n|&lt;br&gt;
if n &amp;lt; target&lt;br&gt;
less_than &amp;lt;&amp;lt; n&lt;br&gt;
end&lt;/p&gt;

&lt;p&gt;if n &amp;gt; target&lt;br&gt;
greater_than &amp;lt;&amp;lt; n&lt;br&gt;
end&lt;br&gt;
end&lt;/p&gt;

&lt;p&gt;less_than.  =&amp;gt; [1, 2, 3, 4] &lt;br&gt;
greater_than.  =&amp;gt; [6, 7, 8, 9, 10] &lt;/p&gt;

&lt;p&gt;If we use the spaceship operator we can get all 3 values! Less_than, greater_than and equal.  To do this we will use group_by method.  &lt;/p&gt;

&lt;p&gt;numbers = Array(1..10)&lt;br&gt;
 =&amp;gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] &lt;/p&gt;

&lt;p&gt;target = 5&lt;br&gt;
 =&amp;gt; 5 &lt;/p&gt;

&lt;p&gt;numbers.group_by{|n| n &amp;lt;=&amp;gt; target}&lt;br&gt;
 =&amp;gt; {-1=&amp;gt;[1, 2, 3, 4], 0=&amp;gt;[5], 1=&amp;gt;[6, 7, 8, 9, 10]} &lt;/p&gt;

&lt;p&gt;This will help us when wanting to sort array's.  I came across a jakedaywilliams youtube and he demonstrated this way of sorting an array.  I'll use my covid pod names as an example&lt;/p&gt;

&lt;p&gt;pod = ["Rachelle", "Alison", "Jason", "Britt", "Joshua", "Amanda"]&lt;/p&gt;

&lt;p&gt;If I wanted to sort them in ASEC order I could&lt;br&gt;
 p pod.sort! {|a,b| a &amp;lt;=&amp;gt; b }&lt;/p&gt;

&lt;p&gt;["Alison", "Amanda", "Britt", "Jason", "Joshua", "Rachelle"]&lt;br&gt;
 =&amp;gt; ["Alison", "Amanda", "Britt", "Jason", "Joshua", "Rachelle"]&lt;/p&gt;

&lt;p&gt;how about DESC order&lt;br&gt;
p pod.sort! { |a,b| b &amp;lt;=&amp;gt; a }&lt;/p&gt;

&lt;p&gt;["Rachelle", "Joshua", "Jason", "Britt", "Amanda", "Alison"]&lt;br&gt;
 =&amp;gt; ["Rachelle", "Joshua", "Jason", "Britt", "Amanda", "Alison"] &lt;/p&gt;

&lt;p&gt;Pretty neat, right? Can we also have a target name to work with? Let's try... we'll use Jason as a target:&lt;/p&gt;

&lt;p&gt;pod = ["Rachelle", "Alison", "Jason", "Britt", "Joshua", "Amanda"]&lt;br&gt;
 =&amp;gt; ["Rachelle", "Alison", "Jason", "Britt", "Joshua", "Amanda"] &lt;/p&gt;

&lt;p&gt;target = "Jason" &lt;/p&gt;

&lt;p&gt;pod.group_by {|name| name &amp;lt;=&amp;gt; target}&lt;br&gt;
 =&amp;gt; {1=&amp;gt;["Rachelle", "Joshua"], -1=&amp;gt;["Alison", "Britt", "Amanda"], 0=&amp;gt;["Jason"]}&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;note - this does return our array into a hash that has 3 key-value pairs.&lt;/li&gt;
&lt;li&gt; 1 =&amp;gt;["Rachelle", "Joshua"]&lt;/li&gt;
&lt;li&gt;-1 =&amp;gt;["Alison", "Britt", "Amanda"]&lt;/li&gt;
&lt;li&gt; 0 =&amp;gt;["Jason"]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you found this useful. Cheers to persistence and the continuity of learning!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
