<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title class="testimonials__title">Today I Learned</title>
    <description>JetRockets runs this project to catalogue the sharing and accumulation of knowledge as it happens day-to-day.
    </description>
    <link>http://jetrockets.pro/til/posts</link>
    <atom:link href="/til/rss" rel="self" type="application/rss+xml" />
      <item>
        <title>
          <![CDATA[Integrate Drawer inside Stack Navigation in React Native - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/hdgmodpvjs-integrate-drawer-inside-stack-navigation-in-react-native</link>
        <description>
          <![CDATA[<p>I wanted to use more than one navigation in a React Native app.
The documentation didn’t give a clear way to implement this.</p>
<p>Here is what you can do on purpose to add several types of navigation in your React Native app:</p>
<pre><code class="javascript language-javascript">
import { createStackNavigator, createDrawerNavigator } from 'react-navigation';
import * as Screens from './screens/index';
import Drawer from './components/DrawerMenu';
import getDrawerWidth from './utils/scale';

const AppStackNavigator = createStackNavigator({
  home: {
    screen: Screens.MainScreen,
  },
  about: {
    screen: Screens.AboutScreen,
  },
});

const AppNavigator = createDrawerNavigator(
  {
    home: {
       screen: AppStackNavigator,
    },
  },
  {
    contentComponent: Drawer,
    drawerWidth: getDrawerWidth,
    headerMode: 'none',
  }
);

export default AppNavigator;
</code></pre>]]>
        </description>
        <dc:creator>Dmitry Sokolov</dc:creator>
        <pubDate>Mon, 22 Apr 2019 10:45:39 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/hdgmodpvjs-integrate-drawer-inside-stack-navigation-in-react-native</guid>
      </item>
      <item>
        <title>
          <![CDATA[Add conditional properties in JS objects - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/m04kqsetdj-add-conditional-properties-in-js-objects</link>
        <description>
          <![CDATA[<p>How conditionaly add properties to object?</p>
<p>As it turned out, it’s pretty simple:</p>
<pre><code class="js language-js">
const user = { id: 1, name: 'Suhomozgy Andrey' }
const position = 'Frontend Developer'
const userWithPosition = {
  ...user,
  id: 2,
  ...(position &amp;&amp; { position })
}

userWithPosition //=&gt; { id: 2, name: 'Suhomozgy Andrey', position: 'Frontend Developer' }

</code></pre>]]>
        </description>
        <dc:creator>Suhomozgy Andrey</dc:creator>
        <pubDate>Wed, 17 Apr 2019 17:44:21 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/m04kqsetdj-add-conditional-properties-in-js-objects</guid>
      </item>
      <item>
        <title>
          <![CDATA[Create factory with an uploaded file in Rails rspec - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/kycqxkheuq-create-factory-with-an-uploaded-file-in-rails-rspec</link>
        <description>
          <![CDATA[<p>To create a factory with an uploaded file in Rails rspec, needs to be included <code class="inline">ActionDispatch::TestProcess</code> module in the <code class="inline">rails_helper.rb</code> file to use the <code class="inline">#fixture_file_upload</code> method in the factories.</p>
<pre><code class="ruby language-ruby"># spec/rails_helper.rb
include ActionDispatch::TestProcess</code></pre>
<p>In a factory, when setting the attribute value, use the method <code class="inline">#fixture_file_upload</code>, specifying the path and file type.</p>
<pre><code class="ruby language-ruby"># spec/factories/import_file.rb
FactoryBot.define do
  factory :import_file, class: ImportFile do
    data { fixture_file_upload 'spec/fixtures/test_file.pdf', 'application/pdf' }
  end
end</code></pre>]]>
        </description>
        <dc:creator>Dmitry Voronov</dc:creator>
        <pubDate>Thu, 28 Mar 2019 12:47:32 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/kycqxkheuq-create-factory-with-an-uploaded-file-in-rails-rspec</guid>
      </item>
      <item>
        <title>
          <![CDATA[Get most performant function - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/3uibwvinmd-get-most-performant-function</link>
        <description>
          <![CDATA[<p>Let’s say you need to determine which function is execute faster.</p>
<p>Write a function that take array of functions and iterates each of them a certain number of times.
Will use the difference in performance.now() values before and after to get the total time in milliseconds each iteration running.</p>
<p>Play with iterations argument to get more or less reliable results.</p>
<pre><code class="js language-js">const mostPerformantFunction = (fns, iterations = 10000) =&gt; {
  const times = fns.map(fn =&gt; {
    const before = performance.now();
    for (let i = 0; i &lt; iterations; i++) fn();
    return performance.now() - before;
  });
  console.log(times);
  return times.indexOf(Math.min(...times));
};</code></pre>
<pre><code class="js language-js">mostPerformantFunction([
  () =&gt; {
    [1, 2, 3, 4, 5, 6, 7, 8, 9, '10'].every(el =&gt; typeof el === 'number');
  },
  () =&gt; {
    [1, '2', 3, 4, 5, 6, 7, 8, 9, 10].every(el =&gt; typeof el === 'number');
  }
]); // 1</code></pre>]]>
        </description>
        <dc:creator>Suhomozgy Andrey</dc:creator>
        <pubDate>Wed, 20 Mar 2019 09:22:32 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/3uibwvinmd-get-most-performant-function</guid>
      </item>
      <item>
        <title>
          <![CDATA[How to download files with Axios - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/l8dadq8oac-how-to-download-files-with-axios</link>
        <description>
          <![CDATA[<p>A simple example using the Blob() constructor:</p>
<pre><code class="js language-js">export function someFunction(values) {
  return (dispatch) =&gt; {
    ...
    const method = 'GET';
    const url = 'http://go.api/download_file';
    ...
    axios
      .request({
        url,
        method,
        responseType: 'blob', //important
      })
      .then(({ data }) =&gt; {
        const downloadUrl = window.URL.createObjectURL(new Blob([data]));
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.setAttribute('download', 'file.zip'); //any other extension
        document.body.appendChild(link);
        link.click();
        link.remove();
      });
  };
}</code></pre>]]>
        </description>
        <dc:creator>Alex Blinov</dc:creator>
        <pubDate>Wed, 20 Mar 2019 08:37:18 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/l8dadq8oac-how-to-download-files-with-axios</guid>
      </item>
      <item>
        <title>
          <![CDATA[How to conditionally render template in Grape resources? - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/bdjqfcuxab-how-to-conditionally-render-template-in-grape-resources</link>
        <description>
          <![CDATA[<p>Suppose you need to conditionally render some template in a given endpoint of a Grape resource. There is a <code class="inline">env</code> data in Grape::API class that represents Rack environment of the request. <code class="inline">env</code> is just a simple Ruby hash and we can pass the template name to it’s <code class="inline">api.tilt.template</code> key to render that template:</p>
<pre><code class="ruby language-ruby">env['api.tilt.template'] = 'foo/bar.json'</code></pre>
<p>Then let’s define a <code class="inline">render</code> method in Base resourсe:</p>
<pre><code class="ruby language-ruby">class Base &lt; Grape::API
  def self.inherited(subclass)
    super

    subclass.instance_eval do
      helpers do
        def render(template_name)
          env['api.tilt.template'] = template_name
        end
      end
    end
  end
end</code></pre>
<p>Now we can use it in the following way:</p>
<pre><code class="ruby language-ruby">class ContactsResource &lt; Base
  desc 'Create contact', http_codes: [[201, 'Created']]

  post '/contacts' do
    contact = Contact.new(params[:contact])

    if contact.save
      render 'v1/contacts/show.json'
    else
      error!({ errors: contact.errors.full_messages }, 422)
    end
  end
end</code></pre>]]>
        </description>
        <dc:creator>Alexander Spitsyn</dc:creator>
        <pubDate>Tue, 05 Mar 2019 20:34:22 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/bdjqfcuxab-how-to-conditionally-render-template-in-grape-resources</guid>
      </item>
      <item>
        <title>
          <![CDATA[Append string to a route with a slash operator - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/3add7nki8v-append-string-to-a-route-with-a-slash-operator</link>
        <description>
          <![CDATA[<p>If you need to append string to some route to build a path name you can use few ways:</p>
<pre><code class="ruby language-ruby">Rails.root + 'foo/bar'
[Rails.root, 'foo/bar'].join('/')
"#{Rails.root}/foo/bar"</code></pre>
<p>But also there is a <code class="inline">Pathname#/</code> method, so you can append string to route using a slash:</p>
<pre><code class="ruby language-ruby">Rails.root/'foo/bar' # =&gt; #&lt;Pathname:/Users/alex/myproject/foo/bar&gt;</code></pre>
<p>Looks more readable!</p>]]>
        </description>
        <dc:creator>Alexander Spitsyn</dc:creator>
        <pubDate>Tue, 05 Mar 2019 19:55:46 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/3add7nki8v-append-string-to-a-route-with-a-slash-operator</guid>
      </item>
      <item>
        <title>
          <![CDATA[How to add a line break to  PostgreSQL? - #devops]]>
        </title>
        <link>http://jetrockets.pro/til/posts/p4awh4eomn-how-to-add-a-line-break-to-postgresql</link>
        <description>
          <![CDATA[<p>You have to insert some data into your PostgreSQL table that has line break. As a result, the cell will look like this:</p>
<pre><code class="text language-text">First line
Second line</code></pre>
<p>To use “escape sequences” in a string literal you need to use an <a href="https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE">“extended” constant</a>. You can specify the escape character by prefixing the letter E:</p>
<pre><code class="sql language-sql">UPDATE posts SET body = E'First Line\nSecond line.' WHERE id = 2701;</code></pre>]]>
        </description>
        <dc:creator>Arina Shmeleva</dc:creator>
        <pubDate>Mon, 25 Feb 2019 16:28:52 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/p4awh4eomn-how-to-add-a-line-break-to-postgresql</guid>
      </item>
      <item>
        <title>
          <![CDATA[Recompose withContext and getContext. Simple example - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/ow49xlehan-recompose-withcontext-and-getcontext-simple-example</link>
        <description>
          <![CDATA[<p>Very often for nested components you need to transfer some props of the parent. For example size. So, we have the Card component. It contains a Button component.</p>
<pre><code class="javascript language-javascript">  // App.js
  &lt;Card size="sm"&gt;
    {/* ... */}
    &lt;div&gt;
      {/* ... */}
      &lt;Button size="sm" onClick={action}&gt;Action&lt;/Button&gt;
    &lt;/div&gt;
  &lt;/Card&gt;
</code></pre>
<p>The size for both components is set by the “size” parameter. In the example above, the parameter passed is indicated for both components. In order not to specify the size for the Button each time, you can use the Context to use the one specified for the Card. If you use recompose, it can be super easy:</p>
<pre><code class="javascript language-javascript">  // Card.js
  import { getContext } from 'recompose';
  // ...
  export default withContext(
    { size: PropTypes.oneOf(['sm', 'md', 'lg']) },
    ({ size }) =&gt; ({ size }),
  )(Card);
  
  // App.js
  import Button from './Button';
  // ...
  const EnhancedButton = getContext({ size: PropTypes.oneOf(['sm', 'md', 'lg']) })(Button);</code></pre>
<p><a href="https://codesandbox.io/embed/rr4kl4725q?fontsize=14">Live example</a></p>]]>
        </description>
        <dc:creator>Alexander Ivlev</dc:creator>
        <pubDate>Sat, 23 Feb 2019 18:23:17 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/ow49xlehan-recompose-withcontext-and-getcontext-simple-example</guid>
      </item>
      <item>
        <title>
          <![CDATA[AND & OR Operators Precedence - #ruby]]>
        </title>
        <link>http://jetrockets.pro/til/posts/sqsqetlino-and-or-operators-precedence</link>
        <description>
          <![CDATA[<p>Are you still sure that <code class="inline">&amp;&amp;</code> and <code class="inline">and</code> is the same operators? Look at this:</p>
<pre><code class="ruby language-ruby">a = true &amp;&amp; false
a
=&gt; false</code></pre>
<pre><code class="ruby language-ruby">a = true and false
a
=&gt; true</code></pre>
<p>The same situation could be reproduced for <code class="inline">||</code> and <code class="inline">or</code>. Why? The answer lies in <a href="https://ruby-doc.org/core/doc/syntax/precedence_rdoc.html">Ruby Operator Precedence</a>.</p>
<p>The first example can be represented as:</p>
<pre><code class="ruby language-ruby">a = (true &amp;&amp; false)</code></pre>
<p>Second:</p>
<pre><code class="ruby language-ruby">(a = true) and false</code></pre>
<p><a href="https://habr.com/en/post/94566/">Thanks to Igor Alexandrov</a></p>]]>
        </description>
        <dc:creator>Alexander Budchanov</dc:creator>
        <pubDate>Wed, 20 Feb 2019 12:59:27 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/sqsqetlino-and-or-operators-precedence</guid>
      </item>
      <item>
        <title>
          <![CDATA[Sort lines in the vim editor - #devops]]>
        </title>
        <link>http://jetrockets.pro/til/posts/bt2bghelui-sort-lines-in-the-vim-editor</link>
        <description>
          <![CDATA[<p>Often when writing code, you need to sort the lines in alphabetical order. For example, in javascript, when importing a large number of modules, it is good practice to organize them alphabetically. Users of the vim editor can do this very simply. It is enough to select in the visual mode all the lines that need to be sorted and enter the command <code class="inline">:sort</code>. All rows are sorted!</p>]]>
        </description>
        <dc:creator>Alexander Ivlev</dc:creator>
        <pubDate>Wed, 20 Feb 2019 12:04:22 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/bt2bghelui-sort-lines-in-the-vim-editor</guid>
      </item>
      <item>
        <title>
          <![CDATA[Custom onChange in React Final Form - #react]]>
        </title>
        <link>http://jetrockets.pro/til/posts/0q1tcsfda0-custom-onchange-in-react-final-form</link>
        <description>
          <![CDATA[<p>Let’s take a case when we need to call our own function to change a state of a specific field in a form (our react final form).</p>
<p>Here is a way to do the exact that:
You should pass your function as a parameter and after that just call it inside of the onChange method</p>
<p>Example:</p>
<pre><code class="js language-js">const FormGroupAdapter = ({ input, inputOnChange }) =&gt; {
    const inputProps = {
        ...input,
        onChange: e =&gt; {
            input.onChange(e);
            inputOnChange &amp;&amp; inputOnChange(e);
        }
    };

    return &lt;input {...inputProps} /&gt;;
};

const handleChange = event =&gt; {
    console.log("!!!", event.target.value);
};

const App = () =&gt; (
    &lt;Form
        ...
        render={({ handleSubmit, reset, submitting, pristine, values }) =&gt; (
            &lt;form onSubmit={handleSubmit}&gt;
                &lt;div&gt;
                    &lt;label&gt;some label&lt;/label&gt;
                    &lt;Field
                        name="someField"
                        component={FormGroupAdapter}
                        inputOnChange={handleChange}
                    /&gt;
                &lt;/div&gt;
                ...
            &lt;/form&gt;
        )}
    /&gt;
);
</code></pre>
<p><a href="https://codesandbox.io/s/nk63v7615j">Live example</a></p>]]>
        </description>
        <dc:creator>Alex Blinov</dc:creator>
        <pubDate>Wed, 20 Feb 2019 11:02:11 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/0q1tcsfda0-custom-onchange-in-react-final-form</guid>
      </item>
      <item>
        <title>
          <![CDATA[Elixir code formatting in IDE (with Atom set up example) - #elixir]]>
        </title>
        <link>http://jetrockets.pro/til/posts/rbmcfykc29-elixir-code-formatting-in-ide-with-atom-set-up-example</link>
        <description>
          <![CDATA[<p>Today I learned that Elixir has a great feature that allows you to format your code.</p>
<p>Here are a few reasons you may want to do that (borrowed from <a href="https://blog.golang.org/go-fmt-your-code">The Go Blog</a>):</p>
<ul>
<li>easier to write: never worry about minor formatting concerns,
</li>
<li>easier to read: when all code looks the same you need not mentally convert others’ formatting style into something you can understand.
</li>
<li>easier to maintain: diffs show only the real changes.
</li>
<li>uncontroversial: never have a debate about spacing or brace position ever again
</li>
</ul>
<p>In fact, you actually want to format your Elixir code as you make it, meaning there is no need to format all of your project’s code every time. </p>
<p>The following bash command does it well on a single file:
<code class="inline">cd $projectPath &amp;&amp; mix format $filePath</code></p>
<p>Where: <code class="inline">$projectPath</code> - full path to your project’s root directory; <code class="inline">$filePath</code> - full path to a file you’re saving</p>
<p>My IDE of choice happened to be <a href="https://atom.io/">Atom</a> and I’ll talk briefly on setting it up.
The <a href="https://atom.io/packages/process-palette">Process Palette</a> package so far is the best for this task. 
My Shell Command field (with variables) in Process Palette looks the following <code class="inline">cd {projectPath} &amp;&amp; mix format {fileAbsPath}</code></p>]]>
        </description>
        <dc:creator>Vitaly Platonov</dc:creator>
        <pubDate>Wed, 20 Feb 2019 09:31:40 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/rbmcfykc29-elixir-code-formatting-in-ide-with-atom-set-up-example</guid>
      </item>
      <item>
        <title>
          <![CDATA[How to display numbers with currency formatting in JS? - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/sypnswfg5k-how-to-display-numbers-with-currency-formatting-in-js</link>
        <description>
          <![CDATA[<p>Use Intl.NumberFormat to enable country / currency sensitive formatting.</p>
<pre><code class="js language-js">const toCurrency = (n, curr, LanguageFormat = undefined) =&gt;
  Intl.NumberFormat(LanguageFormat, { style: 'currency', currency: curr }).format(n);</code></pre>
<pre><code class="js language-js">toCurrency(123456.789, 'EUR'); // €123,456.79  | currency: Euro | currencyLangFormat: Local
toCurrency(123456.789, 'RUB'); // RUB 123,456.79  | currency: Ruble | currencyLangFormat: Local
toCurrency(123456.789, 'RUB', 'Ru-ru') // 123 456,79 ₽  | currency: Ruble | currencyLangFormat: Russian
toCurrency(123456.789, 'USD', 'en-us'); // $123,456.79  | currency: US Dollar | currencyLangFormat: English (United States)
toCurrency(123456.789, 'USD', 'fa'); // ۱۲۳٬۴۵۶٫۷۹ ؜$ | currency: US Dollar | currencyLangFormat: Farsi
toCurrency(322342436423.2435, 'JPY'); // ¥322,342,436,423 | currency: Japanese Yen | currencyLangFormat: Local
toCurrency(322342436423.2435, 'JPY', 'fi'); // 322 342 436 423 ¥ | currency: Japanese Yen | currencyLangFormat: Finnish</code></pre>]]>
        </description>
        <dc:creator>Suhomozgy Andrey</dc:creator>
        <pubDate>Wed, 20 Feb 2019 07:53:18 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/sypnswfg5k-how-to-display-numbers-with-currency-formatting-in-js</guid>
      </item>
      <item>
        <title>
          <![CDATA[Safe Navigation vs Try in Rails (Part 2: Performance) - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/nswsheigth-safe-navigation-vs-try-in-rails-part-2-performance</link>
        <description>
          <![CDATA[<p>This Note is an extension of <a href="/til/posts/ats3ic6xvx-safe-navigation-vs-try-in-rails-part-1-basic-differences">Safe Navigation vs Try in Rails (Part 1: Basic Differences)</a></p>
<p>Method <code class="inline">try()</code> comes from Active Support component of Ruby on Rails. Safe Navigation Operator is Ruby native feature.</p>
<p>Let’s check performance!</p>
<pre><code class="ruby language-ruby">require 'benchmark'

class Foo
  attr_accessor :name
end

foo = Foo.new
bar = nil

Benchmark.bm(35) do |x|
  x.report('Successful access: try(...): ')         { 1_000_000.times { foo.try(:name) } }
  x.report('Successful access: &amp;.: ')               { 1_000_000.times { foo&amp;.name } }
  x.report('Successful access: control sample: ')   { 1_000_000.times { foo.name } }
  x.report('Failed access: try(...): ')             { 1_000_000.times { bar.try(:nonexistent) } }
  x.report('Failed access: safe navigation: ')      { 1_000_000.times { bar&amp;.nonexistent } }
end;nil</code></pre>
<pre><code class=" language-">                                          user     system      total        real
Successful access: try(...):          0.498216   0.005748   0.503964 (  0.530010)
Successful access: &amp;.:                0.062146   0.000943   0.063089 (  0.069714)
Successful access: control sample:    0.062411   0.001098   0.063509 (  0.069603)
Failed access: try(...):              0.172535   0.004374   0.176909 (  0.194386)
Failed access: safe navigation:       0.054141   0.001029   0.055170 (  0.065502)</code></pre>
<p>Safe navigation is about 7 times faster than method <code class="inline">try()</code> for successful navigation and 3 times faster for unsuccessful.</p>]]>
        </description>
        <dc:creator>Alexander Budchanov</dc:creator>
        <pubDate>Tue, 19 Feb 2019 12:35:28 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/nswsheigth-safe-navigation-vs-try-in-rails-part-2-performance</guid>
      </item>
      <item>
        <title>
          <![CDATA[Safe Navigation vs Try in Rails (Part 1: Basic Differences) - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/ats3ic6xvx-safe-navigation-vs-try-in-rails-part-1-basic-differences</link>
        <description>
          <![CDATA[<p>There are some ways of preventing errors like <code class="inline">undefined method for nil:NilClass</code>.</p>
<ul>
<li>Rails Method <code class="inline">try(...)</code>
</li>
<li>Safe Navigation Operator (<code class="inline">&amp;.</code>)
</li>
<li>Logical operator <code class="inline">&amp;&amp;</code> (AND)
</li>
</ul>
<p>Here is how these options look like:</p>
<pre><code class="ruby language-ruby">user.try(:company).try(:name)</code></pre>
<pre><code class="ruby language-ruby">user&amp;.company&amp;.name</code></pre>
<pre><code class="ruby language-ruby">user &amp;&amp; user.company &amp;&amp; user.company.name</code></pre>
<p>But there are some differences.</p>
<p><strong>1. If model User hasn’t relation <code class="inline">compppany</code> (it may be just a typo or renamed model relation/attribute):</strong></p>
<pre><code class="ruby language-ruby">user.try(:compppany).try(:name)
=&gt; nil</code></pre>
<p>You will receive <code class="inline">nil</code> and never been know about this typo.</p>
<pre><code class="ruby language-ruby">user&amp;.compppany&amp;.name
=&gt; NoMethodError: undefined method `compppany' for #&lt;User:0x000000123456789&gt;</code></pre>
<p>and</p>
<pre><code class="ruby language-ruby">user &amp;&amp; user.compppany &amp;&amp; user.compppany.name
=&gt; NoMethodError: undefined method `compppany' for #&lt;User:0x000000123456789&gt;</code></pre>
<p>Looks better!</p>
<p><strong>2. If model User has relation company, but company is <code class="inline">false</code>. <code class="inline">User.new(company: false)</code>:</strong></p>
<pre><code class="ruby language-ruby">user.try(:company).try(:name)
=&gt; nil</code></pre>
<pre><code class="ruby language-ruby">user&amp;.company&amp;.name
=&gt; NoMethodError: undefined method `name' for false:FalseClass</code></pre>
<p>Safe Navigation recognized <code class="inline">false</code>. Awesome!</p>
<pre><code class="ruby language-ruby">user &amp;&amp; user.company &amp;&amp; user.company.name
=&gt; false</code></pre>
<p>Hmmm, it does not look like we want.</p>
<p><strong>3. Performance</strong>
Read the second part <a href="/til/posts/nswsheigth-safe-navigation-vs-try-in-rails-part-2-performance">Safe Navigation vs Try in Rails (Part 2: Performance)</a></p>]]>
        </description>
        <dc:creator>Alexander Budchanov</dc:creator>
        <pubDate>Tue, 19 Feb 2019 12:35:00 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/ats3ic6xvx-safe-navigation-vs-try-in-rails-part-1-basic-differences</guid>
      </item>
      <item>
        <title>
          <![CDATA[Force Downloading of File instead of Opening in Browser - #devops]]>
        </title>
        <link>http://jetrockets.pro/til/posts/wcxpnv9w4j-force-downloading-of-file-instead-of-opening-in-browser</link>
        <description>
          <![CDATA[<p>When you go through the link, some files will be opened in the browser. Such behavior is typical for some content types (e.g., images, pdf, etc.)</p>
<p>However, you can force file downloading instead of opening when an user clicks on the link though.</p>
<h3>1st way (frontend):</h3>
<p>HTML attribute <em>download</em> allows you to do this.</p>
<pre><code class="html language-html">&lt;a href="/public/report.pdf" download="stat_report"&gt;</code></pre>
<p>If the value of the attribute is omitted, the original filename would be used.
However, be careful. This attribute isn’t supported in some old browsers without HTML5 support.
Renaming does not work if the given file stored on another host.</p>
<h3>2nd way (backend):</h3>
<p>You can set HTTP header <code class="inline">Content-disposition</code>.</p>
<p>for Nginx:</p>
<pre><code class="nginx language-nginx">location ~* /public/(.+\.pdf)$ {
    add_header Content-disposition "attachment; filename=$1";
}</code></pre>
<p>for Apache:</p>
<pre><code class="apacheconf language-apacheconf">&lt;IfModule mod_headers.c&gt;
    &lt;FilesMatch "\.(?i:pdf)$"&gt;
        ForceType application/octet-stream
        Header set Content-Disposition "attachment"
    &lt;/FilesMatch&gt;
&lt;/IfModule&gt;</code></pre>]]>
        </description>
        <dc:creator>Alexander Budchanov</dc:creator>
        <pubDate>Mon, 18 Feb 2019 14:27:18 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/wcxpnv9w4j-force-downloading-of-file-instead-of-opening-in-browser</guid>
      </item>
      <item>
        <title>
          <![CDATA[How to delete polymorphic models cascade - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/izca8kaqvq-how-to-delete-polymorphic-models-cascade</link>
        <description>
          <![CDATA[<p>If you use a polymorphic model in your Rails application, like in example</p>
<pre><code class="ruby language-ruby">class Trade &lt; ActiveRecord::Base
  has_many :gl_entries, as: :source, dependent: :destroy
end

class GlEntry &lt; ActiveRecord::Base
  belongs_to :source, polymorphic: true
end</code></pre>
<p>You will not be able to add the usual foreign keys for cascading delete records. But this can be implemented using a database.</p>
<p>To do this, you need to write a trigger in the database that will run the delete function for each record. </p>
<pre><code class="sql language-sql">CREATE FUNCTION deleteGlEntriesOfTrade()
  RETURNS TRIGGER
  SET SCHEMA 'public'
  LANGUAGE plpgsql 
  AS $$
  BEGIN
    DELETE FROM gl_entries WHERE source_id = OLD.id AND source_type = 'Trade';
    RETURN OLD;   
  END;
  $$;
      
CREATE TRIGGER deleteTradesGlEntriesTrigger 
  BEFORE DELETE ON trades
  FOR EACH ROW EXECUTE PROCEDURE deleteGlEntriesOfTrade();</code></pre>
<p>Create a migration and use :) </p>]]>
        </description>
        <dc:creator>Dmitry Voronov</dc:creator>
        <pubDate>Tue, 12 Feb 2019 16:13:25 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/izca8kaqvq-how-to-delete-polymorphic-models-cascade</guid>
      </item>
      <item>
        <title>
          <![CDATA[Sidekiq Stats in Rails - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/aqghrotqhk-sidekiq-stats-in-rails</link>
        <description>
          <![CDATA[<p>If you use Sidekiq in your Rails project, you can watch tasks statistics through the web interface. Usually, you can find it here: https://yourdomain.com<strong>/sidekiq</strong> (but in your project path may be different).
If you don’t have access there, you can get the same data in Rails console.</p>
<p>To get statistics (number of tasks) by each queue:</p>
<pre><code class="ruby language-ruby">Sidekiq::Stats.new.queues
=&gt; {"local_cache"=&gt;0, "default"=&gt;0, "ts_delta"=&gt;0, "mailchimp"=&gt;0, "recorder"=&gt;0}</code></pre>
<p>Global statistics are available this way:</p>
<pre><code class="ruby language-ruby">Sidekiq::Stats.new.fetch_stats!
=&gt; {:processed=&gt;61390,
 :failed=&gt;3220,
 :scheduled_size=&gt;0,
 :retry_size=&gt;0,
 :dead_size=&gt;4,
 :processes_size=&gt;1,
 :default_queue_latency=&gt;0,
 :workers_size=&gt;0,
 :enqueued=&gt;0}</code></pre>
<p>The same stats are available separately:</p>
<pre><code class="ruby language-ruby">stats = Sidekiq::Stats.new
stats.processed # number of processed tasks
stats.failed # number of failed tasks
stats.enqueued # number of enqueued tasks</code></pre>
<p>and etc.</p>
<p>Also <code class="inline">Sidekiq::Stats</code> allows to look historical data. You can specify period. Something like:</p>
<pre><code class="ruby language-ruby">s = Sidekiq::Stats::History.new(2, Date.parse('2019-02-05'))</code></pre>
<ul>
<li>first argument: number of days,
</li>
<li>second argument: date until which return stats (default value is today and can be omitted)
</li>
</ul>
<pre><code class="ruby language-ruby">s.processed
=&gt; {"2019-02-05"=&gt;0, "2019-02-04"=&gt;0}
s.failed
=&gt; {"2019-02-05"=&gt;0, "2019-02-04"=&gt;0}</code></pre>]]>
        </description>
        <dc:creator>Alexander Budchanov</dc:creator>
        <pubDate>Mon, 11 Feb 2019 15:43:55 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/aqghrotqhk-sidekiq-stats-in-rails</guid>
      </item>
      <item>
        <title>
          <![CDATA[Keep clean your git repos! - #devops]]>
        </title>
        <link>http://jetrockets.pro/til/posts/dgsqvlarbw-keep-clean-your-git-repos</link>
        <description>
          <![CDATA[<p>Many developers don’t keep their local repositories clean. There is a way how to automate it though. Let’s look at a few useful commands:</p>
<p><em>To clean refs to nonexistent branches in the remote:</em></p>
<pre><code class="bash language-bash">$ git fetch --prune</code></pre>
<p><code class="inline">--prune</code> before fetching, remove any remote-tracking references that no longer exist on the remote.</p>
<p><em>To estimate how many branches merged into dev:</em></p>
<pre><code class="bash language-bash">$ git branch --merged dev | wc -l</code></pre>
<p><code class="inline">--merged</code> option can filter list to branches that you have merged into the given branch. Squash and rebase merges usually aren’t detected by <code class="inline">--merged</code>.</p>
<p><em>List of branches merged into dev:</em></p>
<pre><code class="bash language-bash">$ git branch --merged dev</code></pre>
<p><em>List of remote branches merged into dev:</em></p>
<pre><code class="bash language-bash">$ git branch --merged dev --remote</code></pre>
<p><em>If you are courageous then:</em></p>
<pre><code class="bash language-bash">$ git branch --merged dev | egrep -v "(^\*|master|dev)" | xargs git branch -d</code></pre>
<p>It removes all local branches that merged into dev (except dev and master).
<strong>This is a potentially damaging operation. It can delete branches actually needed.</strong>
So if you use the different approach to work with Git, you could remove some of branches manually instead. I hope you do not store all old branches, do you?</p>]]>
        </description>
        <dc:creator>Alexander Budchanov</dc:creator>
        <pubDate>Wed, 06 Feb 2019 12:55:33 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/dgsqvlarbw-keep-clean-your-git-repos</guid>
      </item>
      <item>
        <title>
          <![CDATA[Getting rid of inefficient constantize - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/z8u6cklajf-getting-rid-of-inefficient-constantize</link>
        <description>
          <![CDATA[<p>Trying to improve performance of one controller I’ve found the following:</p>
<pre><code class="ruby language-ruby">def application_klass
  @application_klass ||= "application/#{params[:type]}".classify.constantize
end</code></pre>
<p>There are <code class="inline">Application::Rental</code> and <code class="inline">Application::Bridge</code> models in our rails app, so the method above was used in two places:</p>
<ol>
<li><code class="inline">application_klass.to_s</code> – to get the model name as a string
</li>
<li><code class="inline">application_klass.model_name.human</code> – to get a class name without module prefix
</li>
</ol>
<p>I’ve refactored method in the following way:</p>
<pre><code class="ruby language-ruby">def application_klass
  @application_klass ||= "application/#{params[:type]}".classify
end </code></pre>
<p>And it’s occurrences now looks like this:</p>
<ol>
<li><code class="inline">application_klass</code> – just call this method to get a model name
</li>
<li><code class="inline">application_klass.demodulize</code> – using <code class="inline">demodulize</code> to split a string with <code class="inline">::</code>
</li>
</ol>
<p>I’ve got rid of unnecessary <code class="inline">constantize</code> method, which is quite inefficient: just imagine that your application tries to find a constant in your project with the name specified in the string. See the benchmarks below to evaluate performance gains:</p>
<pre><code class="ruby language-ruby">counter = 100_000
type = 'Rental'

Benchmark.bm(30) do |x|
  x.report('demodulize: ')                   { counter.times { "application/#{type}".classify.demodulize } }
  x.report('constantize.model_name.human: ') { counter.times { "application/#{type}".classify.constantize.model_name.human } }
end

                                     user     system      total        real
demodulize:                      3.560000   0.760000   4.320000 (  4.381891)
constantize.model_name.human:    8.500000   0.070000   8.570000 (  8.601007)</code></pre>]]>
        </description>
        <dc:creator>Alexander Spitsyn</dc:creator>
        <pubDate>Mon, 04 Feb 2019 15:00:50 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/z8u6cklajf-getting-rid-of-inefficient-constantize</guid>
      </item>
      <item>
        <title>
          <![CDATA[Use hash or case-statement in Ruby? - #ruby]]>
        </title>
        <link>http://jetrockets.pro/til/posts/gtess8a8d7-use-hash-or-case-statement-in-ruby</link>
        <description>
          <![CDATA[<p>Often, when we need to get a value based on the other one, we’re using a case-statement. Like this</p>
<pre><code class="ruby language-ruby">def realizing_trade_type(realizable_trade_type)
  case realizable_trade_type
  when 'buy'
    'sell'
  when 'short'
    'cover'
  when 'buy_contract'
    'sell_contract'
  when 'short_contract'
    'cover_contract'
  end
end</code></pre>
<p>But, if the conditions and the results are simple values, why don’t we use hash for this? We can :)</p>
<pre><code class="ruby language-ruby">REALIZING_TRADE_TYPES = {
  'buy'            =&gt; 'sell',
  'short'          =&gt; 'cover',
  'buy_contract'   =&gt; 'sell_contract',
  'short_contract' =&gt; 'cover_contract'
}.freeze</code></pre>
<p>Here is the benchmark of both options, executed 10_000_000 times. It shows that a hash is faster in times for such the kind of usage.</p>
<pre><code class="bash language-bash">&gt;&gt; require 'benchmark'
true
&gt;&gt; Benchmark.bm(15) do |x|
  x.report('hash') { 10_000_000.times { REALIZING_TRADE_TYPES['buy'] } }
  x.report('case-statement') { 10_000_000.times { realizing_trade_type 'buy' } }
  x.report('empty') { 10_000_000.times {} }
end
                      user     system      total        real
hash              0.990423   0.003412   0.993835 (  1.057612)
case-statement    1.752263   0.004531   1.756794 (  1.762030)
empty             0.380810   0.000728   0.381538 (  0.382153)</code></pre>
<p>So, it’s better to use a hash when you are just retrieving some values (like in the example above). If there is additional logic to execute, a case-statement is still a way to go.</p>]]>
        </description>
        <dc:creator>Dmitry Voronov</dc:creator>
        <pubDate>Sun, 03 Feb 2019 18:39:54 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/gtess8a8d7-use-hash-or-case-statement-in-ruby</guid>
      </item>
      <item>
        <title>
          <![CDATA[Form_for and Rails attributes API - #rails]]>
        </title>
        <link>http://jetrockets.pro/til/posts/82iki9uisb-formfor-and-rails-attributes-api</link>
        <description>
          <![CDATA[<p>Attributes API allows you to have complex object with specified structure in fields. But how to make forms with this fields?</p>
<p>The answer is pretty simple: you work with them like with nested attributes.</p>
<p>Let’s say, we have class Provider with attribute address. </p>
<pre><code class="ruby language-ruby">class Provider &lt; ApplicationRecord
  attribute :address, Provider::Address::Type.new, default: Provider::Address.new</code></pre>
<p>Address has following attributes:</p>
<pre><code class="ruby language-ruby">class Provider::Address
  extend Dry::Initializer

  option :country, optional: true
  option :zip, optional: true
  option :city, optional: true
  option :address, optional: true</code></pre>
<p>Form will look like this:</p>
<pre><code class="ruby language-ruby">= form_for resource_provider, provider_url do |f|
  = f.fields_for :address do |ff|
      = ff.label 'Country'
      = ff.text_field :country, value: @provider.billing_address.country
      
      = ff.label 'Zip'
      = ff.text_field :zip, value: @provider.billing_address.zip
      
      = ff.label 'City'
      = ff.text_field :city, value: @provider.billing_address.city
      
      = ff.label 'Address'
      = ff.text_field :address, value: @provider.billing_address.address</code></pre>
<p>In controller you have to permit parameters:</p>
<pre><code class="ruby language-ruby">def provider_params
    params.require(:provider).permit(address: [:city, :zip, :country, :address])
end</code></pre>
<p>And that’s all. Now, in action method you can assign attributes like this:</p>
<pre><code class="ruby language-ruby">resource_provider.attributes = provider_params
resource_provider.save</code></pre>]]>
        </description>
        <dc:creator>Maksim Agafonov</dc:creator>
        <pubDate>Thu, 31 Jan 2019 09:45:38 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/82iki9uisb-formfor-and-rails-attributes-api</guid>
      </item>
      <item>
        <title>
          <![CDATA[Passing events between browser tabs without WebSockets - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/yw9lict12q-passing-events-between-browser-tabs-without-websockets</link>
        <description>
          <![CDATA[<p>What if need to pass some event from one browser tab to each others? And we don’t have WebSockets…</p>
<p>It turns out that localStorage raises events 😍</p>
<p>Namely, events are triggered when an item is added, deleted, or changed in another context. In essence, this means that when you change localStorage in one tab, other tabs can find out about this by listening to the storage event of the global window object. For example:</p>
<pre><code class="js language-js">  window.addEventListener('storage', function (event) {
    console.log(event.key, event.newValue);
  });</code></pre>
<p>Of course, there are some restrictions on use (you can read about them here <a href="https://www.w3.org/TR/webstorage/">https://www.w3.org/TR/webstorage/</a>), but for simple cases it is match perfect.</p>]]>
        </description>
        <dc:creator>Suhomozgy Andrey</dc:creator>
        <pubDate>Tue, 29 Jan 2019 09:46:53 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/yw9lict12q-passing-events-between-browser-tabs-without-websockets</guid>
      </item>
      <item>
        <title>
          <![CDATA[Rename the key name in the javascript object - #javascript]]>
        </title>
        <link>http://jetrockets.pro/til/posts/rmvzzosmz9-rename-the-key-name-in-the-javascript-object</link>
        <description>
          <![CDATA[<p>How to rename the key name in the javascript object? That’s easy!</p>
<p>Lets create function to do that:</p>
<pre><code class="js language-js">const renameKey = (object, key, newKey) =&gt; {
  const clonedObj = clone(object);
  const targetKey = clonedObj[key];

  delete clonedObj[key];
  clonedObj[newKey] = targetKey;
  return clonedObj;
};</code></pre>
<p>Here is clone function:</p>
<pre><code class="js language-js">const clone = (obj) =&gt; Object.assign({}, obj);</code></pre>
<p>Example:</p>
<pre><code class="js language-js">let contact = { 
    id: 1, 
    name: "contact name"
};

contact = renameKey(contact, 'id', 'value');
contact = renameKey(contact, 'name', 'label');

console.log(contact); // { value: 1, label: "contact name" };</code></pre>]]>
        </description>
        <dc:creator>Alex Blinov</dc:creator>
        <pubDate>Tue, 29 Jan 2019 08:57:10 GMT</pubDate>
        <guid isPermaLink="true">http://jetrockets.pro/til/posts/rmvzzosmz9-rename-the-key-name-in-the-javascript-object</guid>
      </item>
  </channel>
</rss>
