<?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: SaKKo</title>
    <description>The latest articles on DEV Community by SaKKo (@sakko).</description>
    <link>https://dev.to/sakko</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%2F112196%2F3af1b2e4-b12b-48e5-be45-501486c8133b.jpeg</url>
      <title>DEV Community: SaKKo</title>
      <link>https://dev.to/sakko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sakko"/>
    <language>en</language>
    <item>
      <title>How to setup Mac for development in 2024. (Ruby on Rails and NodeJS)</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Wed, 29 May 2024 06:45:55 +0000</pubDate>
      <link>https://dev.to/sakko/how-to-setup-mac-for-development-in-2024-3bfk</link>
      <guid>https://dev.to/sakko/how-to-setup-mac-for-development-in-2024-3bfk</guid>
      <description>&lt;p&gt;It's been awhile (&lt;a href="https://dev.to/sakko/how-i-upgrade-my-mac-for-development-in-catalina-macos-33g1"&gt;Since my previous post&lt;/a&gt;) and the new members in my teams are having difficulties setting up their new laptop. (Especially if they are previously Windows user)&lt;/p&gt;

&lt;p&gt;So let's begin, &lt;/p&gt;

&lt;h1&gt;
  
  
  The good username (Account name)
&lt;/h1&gt;

&lt;p&gt;If you happen to read this before you first setup your mac, you should try to setup your username to be &lt;code&gt;lowercase with no space&lt;/code&gt;.&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%2Fuploads%2Farticles%2Fltjcit2gz7mkdn50tgyq.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%2Fuploads%2Farticles%2Fltjcit2gz7mkdn50tgyq.png" alt="The good username"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is because there will be time you want to access the path directly and your don't want to mistyped &lt;code&gt;/Users/sakko&lt;/code&gt; vs &lt;code&gt;/Users/SaKKo&lt;/code&gt;. (This path will be your &lt;code&gt;~&lt;/code&gt; or $HOME directory) By simplifying the username, it might save you a lot of time since in Ubuntu they setup the username as &lt;code&gt;/home/ubuntu&lt;/code&gt; as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  XCode or Just CLI
&lt;/h1&gt;

&lt;p&gt;Every mac is nearly ready for software development. The easiest way to get start is to just install Xcode from App Store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/xcode/" rel="noopener noreferrer"&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%2Fuploads%2Farticles%2Fwlw3qy0s4pjv2b69e8po.png" alt="Xcode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are like me, you only want to install what you are using. So, unless you are immediately writing iOS application, then don't install xcode just yet. Instead press &lt;code&gt;⌘+space&lt;/code&gt; and type terminal. &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%2Fuploads%2Farticles%2F3i7602y6ijo1yrnjexd1.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%2Fuploads%2Farticles%2F3i7602y6ijo1yrnjexd1.png" alt="Open Terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And just run this command in terminal. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

xcode-select &lt;span class="nt"&gt;--install&lt;/span&gt;


&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%2Fuploads%2Farticles%2Fpayw9cl0vzr192lknqsr.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%2Fuploads%2Farticles%2Fpayw9cl0vzr192lknqsr.png" alt="xcode-select --install"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There should be a popup. Click install and then complete the installation processes.&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%2Fuploads%2Farticles%2Fk8nw6gh40poztne8jbob.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%2Fuploads%2Farticles%2Fk8nw6gh40poztne8jbob.png" alt="xcode-select --install popup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it's done, you should restart the terminal session. The easiest way is to click at the current terminal window and press &lt;code&gt;⌘+w&lt;/code&gt; to close current tab. Then press &lt;code&gt;⌘+t&lt;/code&gt; to start a new tab. Also note that this shortcut is usable in other apps as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  Homebrew
&lt;/h1&gt;

&lt;p&gt;I know some might disagree, but Homebrew is a real time-saver for me. Here is the link for you to get start (or just keep reading)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://brew.sh/" rel="noopener noreferrer"&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%2Fuploads%2Farticles%2Fvrub7uw68g9b24wuqujm.png" alt="Homebrew website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simply run this command in terminal&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;


&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%2Fuploads%2Farticles%2Fr28tvbt3eiy3vu48dxg1.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%2Fuploads%2Farticles%2Fr28tvbt3eiy3vu48dxg1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 3 steps here&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;paste the command&lt;/li&gt;
&lt;li&gt;type your password (you can't see it, just type and press enter)&lt;/li&gt;
&lt;li&gt;Just press enter to confirm installation path. (Don't input anything else) You don't want to mess with this path.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When everything stop, many people will think that it's done. But it's not, you must copy the command in the &lt;code&gt;Next steps:&lt;/code&gt; section and run it in terminal. NOTE: Copy both lines, don't miss any.&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%2Fuploads%2Farticles%2F7kyvhr3mdih4mz6ob0qv.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%2Fuploads%2Farticles%2F7kyvhr3mdih4mz6ob0qv.png" alt="After Homebrew finish installing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you missed it, here is the command. ($HOME is your home directory)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'eval "$(/opt/homebrew/bin/brew shellenv)"'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.zprofile
&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;/opt/homebrew/bin/brew shellenv&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;


&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%2Fuploads%2Farticles%2Fpd3ro63lvc4ajqiud8hh.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%2Fuploads%2Farticles%2Fpd3ro63lvc4ajqiud8hh.png" alt="Run Homebrew zprofile script"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testing brew is simple, just type &lt;code&gt;which brew&lt;/code&gt; and see if you get brew path in return. (&lt;code&gt;which&lt;/code&gt; is a command to check where the binary you want to execute is located)&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%2Fuploads%2Farticles%2Fc106ajwnimu0x45twchz.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%2Fuploads%2Farticles%2Fc106ajwnimu0x45twchz.png" alt="which brew"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing Ruby using RVM
&lt;/h1&gt;

&lt;p&gt;Even if you are not writing Ruby on Rails, there is a chance that you might need to use some Rubygems in the future such as cocoapods. So it won't hurt to install ruby first. Moreover, installing ruby will install many other dependencies you may need in the future. &lt;/p&gt;

&lt;h2&gt;
  
  
  RVM - Ruby Version Manager
&lt;/h2&gt;

&lt;p&gt;RVM will allow you to install many ruby versions in your mac / linux. Simply visit rvm website&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%2Fuploads%2Farticles%2F982mqjs1rphq6ll19ckx.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%2Fuploads%2Farticles%2F982mqjs1rphq6ll19ckx.png" alt="rvm website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and run the highlighted command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="se"&gt;\c&lt;/span&gt;url &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://get.rvm.io | bash &lt;span class="nt"&gt;-s&lt;/span&gt; stable


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When it's done, restart the terminal session (&lt;code&gt;⌘+w&lt;/code&gt; &lt;code&gt;⌘+t&lt;/code&gt;) then type &lt;code&gt;rvm --version&lt;/code&gt; to check if rvm is installed.&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%2Fuploads%2Farticles%2Fc9l5hrvalrur60kp889y.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%2Fuploads%2Farticles%2Fc9l5hrvalrur60kp889y.png" alt="rvm --version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ruby
&lt;/h2&gt;

&lt;p&gt;We will use &lt;code&gt;rvm&lt;/code&gt; to install multiple ruby versions. I usually start installing with older versions (not latest). There are time when openssl may break ruby installation. If you have problem in this step, you need to google for solutions. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

rvm &lt;span class="nb"&gt;install &lt;/span&gt;2.7.4
rvm &lt;span class="nb"&gt;install &lt;/span&gt;3.0.6
rvm &lt;span class="nb"&gt;install &lt;/span&gt;3.1.4
rvm &lt;span class="nb"&gt;install &lt;/span&gt;3.2.2
rvm &lt;span class="nb"&gt;install &lt;/span&gt;3.3.0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You don't need to install all of these. But these are what I have. Switching ruby version is simple. You only need to understand these commands. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

ruby &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="c"&gt;# check current version&lt;/span&gt;
rvm list &lt;span class="c"&gt;# list all installed versions&lt;/span&gt;
rvm list known &lt;span class="c"&gt;# list all known / installable versions &lt;/span&gt;
rvm use VERSION &lt;span class="c"&gt;# eg. `rvm use 3.3.0` will swap to `3.3.0`&lt;/span&gt;
rvm &lt;span class="nt"&gt;--default&lt;/span&gt; use VERSION &lt;span class="c"&gt;# to setup that version as default every time terminal is opened.&lt;/span&gt;


&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%2Fuploads%2Farticles%2Frsqw6jofhnkc6b6vdzbw.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%2Fuploads%2Farticles%2Frsqw6jofhnkc6b6vdzbw.png" alt="RVM example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing Nodejs using NVM
&lt;/h1&gt;

&lt;p&gt;Similar to RVM there is NVM for Nodejs. Fortunately, it's easy to install nvm using homebrew. Just run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

brew &lt;span class="nb"&gt;install &lt;/span&gt;nvm


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will need to copy and paste this text into &lt;code&gt;~/.zshrc&lt;/code&gt;.&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%2Fuploads%2Farticles%2Ft6si4j0ds13ac2v9ixc3.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%2Fuploads%2Farticles%2Ft6si4j0ds13ac2v9ixc3.png" alt="Install nvm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do that just copy the text and then run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

nano ~/.zshrc


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;move the cursor down to the bottom and just paste the text.&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%2Fuploads%2Farticles%2Fuowgf6157bvttr2v7xol.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%2Fuploads%2Farticles%2Fuowgf6157bvttr2v7xol.png" alt="Install nvm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, save the file and exit. (in &lt;code&gt;nano&lt;/code&gt; pressing &lt;code&gt;ctrl+x&lt;/code&gt; will try to exit &lt;code&gt;nano&lt;/code&gt; but since you've made some changes it will ask if you want to save. the prompt is at the bottom of the screen. Select &lt;code&gt;yes&lt;/code&gt; and press enter).&lt;/p&gt;

&lt;p&gt;If you want to check if &lt;code&gt;nvm&lt;/code&gt; is working, just try installing some Nodejs. The commands are listed below&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

nvm list &lt;span class="c"&gt;# list installed versions&lt;/span&gt;
nvm ls-remote &lt;span class="c"&gt;# list installable versions&lt;/span&gt;
nvm &lt;span class="nb"&gt;install &lt;/span&gt;VERSION &lt;span class="c"&gt;# eg. `nvm install 20.14.0`&lt;/span&gt;
nvm use VERSION &lt;span class="c"&gt;# switching version&lt;/span&gt;
nvm &lt;span class="nb"&gt;alias &lt;/span&gt;default VERSION &lt;span class="c"&gt;# making the selected version default every time terminal is opened.&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you are a Node user that depends on .nvmrc to switch versions between projects. Or you are planning to learn nodejs, configuring this will help.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;nano ~/.zshrc&lt;/code&gt; again and paste this at the bottom.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

load-nvmrc() {
  local node_version="$(nvm version)"
  local nvmrc_path="$(nvm_find_nvmrc)"

  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")

    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$node_version" ]; then
      nvm use
    fi
  elif [ "$node_version" != "$(nvm version default)" ]; then
    echo "Reverting to nvm default version"
    nvm use default
  fi
}
add-zsh-hook chpwd load-nvmrc


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Restart the session and this load-nvmrc hook should be active. When you enter any folder using &lt;code&gt;cd&lt;/code&gt; it will always look for &lt;code&gt;.nvmrc&lt;/code&gt; file which usually indicates the Node version inside. eg. &lt;code&gt;v18.20.3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It's hard to explain. So sollow the image below to see how it works.&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%2Fuploads%2Farticles%2Flr490qwxvus8e5jtvdi9.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%2Fuploads%2Farticles%2Flr490qwxvus8e5jtvdi9.png" alt="nvmrc example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker
&lt;/h1&gt;

&lt;p&gt;Though you can install docker via brew and I'm not a big fan of double clicking anything, I still prefer to go to the official website and download the installer. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&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%2Fuploads%2Farticles%2Fa75t17c85lxlv0dfg8yl.png" alt="Docker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's easy, simple, safe and fast.&lt;/p&gt;

&lt;h1&gt;
  
  
  Postgresql
&lt;/h1&gt;

&lt;p&gt;I prefer having database locally. Sometimes docker just take too much storage. With brew, it's easy to install postgres.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

brew &lt;span class="nb"&gt;install &lt;/span&gt;postgresql@16
brew services start postgresql@16


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To test if it's working just try &lt;code&gt;createdb&lt;/code&gt;, &lt;code&gt;psql&lt;/code&gt;, and &lt;code&gt;dropdb&lt;/code&gt;&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%2Fuploads%2Farticles%2Framqi8q3dfboec3fazj6.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%2Fuploads%2Farticles%2Framqi8q3dfboec3fazj6.png" alt="Test Postgres CLI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Other softwares you might need
&lt;/h1&gt;

&lt;p&gt;Maybe you want to install chrome, vscode, sublime text, etc... just google &lt;code&gt;brew install SOFTWARENAME&lt;/code&gt; such as search for &lt;code&gt;brew install chrome&lt;/code&gt;. It will tell you to run install with &lt;code&gt;--cask&lt;/code&gt;.&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%2Fuploads%2Farticles%2Fabczamuhks7q9mcxyrwq.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%2Fuploads%2Farticles%2Fabczamuhks7q9mcxyrwq.png" alt="Brew install chrome"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--cask&lt;/code&gt; option is usually when you are about to install software that has GUIs.&lt;/p&gt;

&lt;p&gt;Here are the list that you might want to install&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;p&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; google-chrome&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; sublime-text&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; visual-studio-code&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; azure-data-studio&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; postman&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; microsoft-teams&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; firefox&lt;br&gt;
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; iterm2&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Sublime&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;I use Sublime as my main IDE and &lt;a href="https://gist.github.com/SaKKo/229091392e9ef9d75d1b5c9b5f4c48dd" rel="noopener noreferrer"&gt;HERE&lt;/a&gt; is my current config.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's next
&lt;/h1&gt;

&lt;p&gt;Well.... installing things are easy. First you search in homebrew then if it's not there then you do it manually.&lt;/p&gt;

&lt;p&gt;I made this post specially for my team members. If you find this article useful please share.&lt;/p&gt;

&lt;p&gt;Thankz&lt;br&gt;
SaKKo&lt;/p&gt;

</description>
      <category>mac</category>
      <category>ruby</category>
      <category>rails</category>
      <category>node</category>
    </item>
    <item>
      <title>Sunsetting Atom... what is your next Editor?</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 09 Jun 2022 11:52:00 +0000</pubDate>
      <link>https://dev.to/sakko/sunsetting-atom-what-is-your-next-editor-2o0o</link>
      <guid>https://dev.to/sakko/sunsetting-atom-what-is-your-next-editor-2o0o</guid>
      <description>&lt;p&gt;I've been using Atom for very long time. To me, it has all I need to write Ruby on Rails, NuxtJS, NextJS, and react-native.&lt;/p&gt;

&lt;p&gt;Now that Atom is going to be archived on December 15, 2022. I'm moving back to Sublime Text. I used to use Sublime Text a lot but I don't really like the color scheme. It's going to take some time to get used to new color scheme.&lt;/p&gt;

&lt;p&gt;Are there anyone moving to Sublime Text instead of VSCode like me?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>NoSQL, why? I love transactional database but I'm not sure if I'm missing anything.</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Sun, 29 May 2022 04:42:13 +0000</pubDate>
      <link>https://dev.to/sakko/nosql-why-i-love-transactional-database-but-im-not-sure-if-im-missing-anything-8il</link>
      <guid>https://dev.to/sakko/nosql-why-i-love-transactional-database-but-im-not-sure-if-im-missing-anything-8il</guid>
      <description>&lt;p&gt;I've developed more than 100 applications over 10 years for my customers and none of them are NoSQL.&lt;/p&gt;

&lt;p&gt;I've tried a few like, mongo, dynamo, firebase, but I don't really understand the use case.&lt;/p&gt;

&lt;p&gt;Moreover, I'm not sure if I can maintain the software for the next 3-8 years without problems querying older data.&lt;/p&gt;

&lt;p&gt;Am I missing anything?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scaling?&lt;/li&gt;
&lt;li&gt;easier change request?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which kind of project should I use NoSQL?&lt;/p&gt;

&lt;p&gt;thankz!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ฟรี IOS Widget Covid ไทย ตัวเลขอัพเดททุกวัน</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 29 Jul 2021 15:48:08 +0000</pubDate>
      <link>https://dev.to/sakko/widget-covid-19-ios-16bk</link>
      <guid>https://dev.to/sakko/widget-covid-19-ios-16bk</guid>
      <description>&lt;p&gt;สวัสดีครับ โพสนี้ทำขึ้นมาเพื่ออธิบายวิธีการเพิ่ม Widget ให้ iOS นะครับ&lt;/p&gt;

&lt;p&gt;สำหรับ Android ดูได้ที่นี่ครับ&lt;br&gt;
--&amp;gt; &lt;a href="https://www.facebook.com/GamingDoseTech/photos/a.320969531811686/958076258101007/"&gt;Android Widget&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scriptable
&lt;/h2&gt;

&lt;p&gt;โหลดแอพ --&amp;gt; &lt;a href="https://scriptable.app/"&gt;scriptable.app&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Script
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/SaKKo/scriptable-covid-ios-widget"&gt;https://github.com/SaKKo/scriptable-covid-ios-widget&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หรือ&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/SaKKo/scriptable-covid-ios-widget/main/index.js"&gt;https://raw.githubusercontent.com/SaKKo/scriptable-covid-ios-widget/main/index.js&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  วีดีโอเพิ่ม Script
&lt;/h2&gt;

&lt;p&gt;วิธีการเพิ่ม สอนเป็นวีดีโอดูผ่าน youtube สำหรับคนอ่านข้างล่างไม่เข้าใจ&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=dUitlz1Cro0"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--byLY0TOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://soontobeprogrammer.com/posts/covid-ios-widget/2.png" alt="iOS Widget Covid 19 youtube"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หรือถ้าไม่ชอบดูวีดีโอ สามารถทำตามนี้ได้ครับ&lt;/p&gt;

&lt;h2&gt;
  
  
  ไม่ชอบดูวีดีโอ ดูรูปแทน
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fg_RAsdc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/1.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fg_RAsdc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/1.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kdaBEysx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/2.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kdaBEysx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/2.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n7_2DpQs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/3.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n7_2DpQs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/3.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CN-mF3nG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/4.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CN-mF3nG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/4.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dP5pJMuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/5.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dP5pJMuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/5.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jqz2YmHW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/6.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jqz2YmHW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/6.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---zzUi1GZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/7.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---zzUi1GZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/7.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SABdVSn6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/8.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SABdVSn6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/8.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cLIDNxCZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/9.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cLIDNxCZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/9.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CFgqIl9M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/10.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CFgqIl9M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/10.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  วิธีเพิ่ม Widget
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pbMljSpS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/11.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pbMljSpS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/11.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3pprhOP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/12.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3pprhOP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/12.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iK1PdpbM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/13.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iK1PdpbM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/13.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3i4z6jMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/14.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3i4z6jMI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/14.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jsruxZqg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/15.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jsruxZqg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/15.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SkRQsDZ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/16.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SkRQsDZ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/16.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BMd7rWFe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/17.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BMd7rWFe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/17.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--15lnVMbq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/18.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--15lnVMbq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/18.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5WAwy0CC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/19.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5WAwy0CC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/19.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MFcwwwas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/20.PNG%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MFcwwwas--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/sakko/scriptable-covid-ios-widget/blob/main/assets/20.PNG%3Fraw%3Dtrue" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  เสร็จแล้วครับ
&lt;/h2&gt;

&lt;p&gt;หวังว่าจะมีประโยชน์นะครับ&lt;br&gt;
ใส่หน้ากากกันด้วยนะครับ&lt;/p&gt;

</description>
      <category>ios</category>
      <category>widget</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Let's prepare your mac for development. Stop having version conflicts.</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 08 Apr 2021 04:19:22 +0000</pubDate>
      <link>https://dev.to/sakko/let-s-prepare-your-mac-for-development-stop-having-version-conflicts-2j26</link>
      <guid>https://dev.to/sakko/let-s-prepare-your-mac-for-development-stop-having-version-conflicts-2j26</guid>
      <description>&lt;p&gt;Hi everyone,&lt;/p&gt;

&lt;p&gt;During my first few years of programming, the first struggle I have is how to manage multiple versions of Ruby.&lt;/p&gt;

&lt;p&gt;It's been a very painful programming experience. I have to keep upgrading Ruby in the older projects in order to maintain them.&lt;/p&gt;

&lt;p&gt;I know it's a good practice to keep everything up to date, but sometimes, it's just a side project and not worth spending time on.&lt;/p&gt;

&lt;p&gt;That was 9 years ago.... If you are having the same problem as me with Ruby, Python, and NodeJS.&lt;/p&gt;

&lt;p&gt;Here is the solution, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby use RVM&lt;/li&gt;
&lt;li&gt;Python use pyenv&lt;/li&gt;
&lt;li&gt;NodeJS use NVM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I made a video to explain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=TUMbUeschdg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HY_sHFa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bm6p0rqg2a2ndy9szkvf.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you find it useful&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>python</category>
      <category>node</category>
    </item>
    <item>
      <title>Soon-to-be Ruby on Rails --api Programmer (writing my first book)</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 03 Dec 2020 12:12:20 +0000</pubDate>
      <link>https://dev.to/sakko/soon-to-be-ruby-on-rails-api-programmer-writing-my-first-book-3jil</link>
      <guid>https://dev.to/sakko/soon-to-be-ruby-on-rails-api-programmer-writing-my-first-book-3jil</guid>
      <description>&lt;p&gt;Hi, I just wanna share my experience about teaching programming in Youtube vs writing books.&lt;/p&gt;

&lt;p&gt;I'm a self taught programmers, I do read a lot and tried my best to completely understand the concept.&lt;br&gt;
I started off with just recording my screen and explained how to do stuffs that I'm comfortable to share.&lt;/p&gt;

&lt;p&gt;First just coding video,&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2o81_sWB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tv6uh067w4v54wmw3f9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2o81_sWB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tv6uh067w4v54wmw3f9d.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I started looking for more ways to present the content by using papers.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k8PbOVRj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r5dkufr2u1s3b1i080tn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k8PbOVRj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r5dkufr2u1s3b1i080tn.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I get around 200~600 views per day and about $0.20 per day. I do now know why the number isn't stable. But it's ok, I'm doing this for fun.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--buAhu5wP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o24idjgh2n2yk4ta8ff5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--buAhu5wP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o24idjgh2n2yk4ta8ff5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I think, I want to try writing a book. So I started writing one in Thai a couple of weeks back. It's difficult to write the first few chapters because there are so many things to explain. I'm now on Chapter 13 in Thai and at 126 pages.&lt;/p&gt;

&lt;p&gt;The purpose of this book is actually to help my new employees to be able to start working on Ruby on Rails without having to bother their seniors. I want them to be able to gain enough knowledge and start asking more question about business not code.&lt;/p&gt;

&lt;p&gt;Then I think, why not sell the book? So, I'm just posting this book (in Thai) in a few facebook groups I know. I didn't do any Ads, I'd like to focus on writing than doing Ads for now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/soon-to-be-ruby-programmer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--neAxDlxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/duytgs22l61an95t66cr.png" alt="หนังสือเกิดอยากเขียน API ด้วย Ruby on Rails"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://leanpub.com/soon-to-be-ruby-programmer"&gt;Link to the book (Thai) =&amp;gt; Leanpub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before I started writing chapter 14, I'm translating my book to English. It's about 70% done and I'm excited to share.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/soon-to-be-ror-programmer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fWceXBR0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y9hrn7m9ccq6aciai64a.png" alt="Soon to be Ruby on Rails --api Programmer"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://leanpub.com/soon-to-be-ror-programmer"&gt;Link to the book (English) =&amp;gt; Leanpub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are about to start Ruby on Rails, please give my book a chance and please give me feedback.&lt;/p&gt;

&lt;p&gt;Thank you very much.&lt;br&gt;
SaKKo&lt;/p&gt;

</description>
      <category>book</category>
      <category>ruby</category>
      <category>rails</category>
      <category>beginners</category>
    </item>
    <item>
      <title>หนังสือสอน Javascript/NodeJS เบื้องต้น สำหรับคนไม่มีพื้นฐานโปรแกรมมิ่ง</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 05 Nov 2020 07:26:11 +0000</pubDate>
      <link>https://dev.to/sakko/javascript-p1c</link>
      <guid>https://dev.to/sakko/javascript-p1c</guid>
      <description>&lt;p&gt;สวัสดีครับ&lt;br&gt;
ผมศักดิ์ครับ ผมทำ &lt;a href="https://youtube.com/sakkosama"&gt;Youtube Channel ชื่อ Sakkosama&lt;/a&gt; มาได้ซักพักนึงแล้วครับ มีคนติดตามนิดหน่อย&lt;/p&gt;

&lt;p&gt;ตอนนี้ผมแต่งหนังสือขึ้นมาเล่มนึง เหมาะสำหรับคนที่ไม่เคยเขียนโปรแกรมมาก่อน&lt;/p&gt;

&lt;p&gt;ชื่อว่า &lt;a href="https://leanpub.com/soon-to-be-programmer"&gt;เกิดอยากจะเป็น โปรแกรมเมอร์&lt;/a&gt; ราคา $9.99 ครับ ใครชอบ channel ผม ช่วยสนับสนุนหน่อยนะครับ &lt;a href="https://leanpub.com/soon-to-be-programmer"&gt;กดซื้อ/สนับสนุนได้ที่นี่เลยครับ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เป็นหนังสือที่ใช้ Javascript สอน ทั้งหมด เนื้อหาประมานนี้ครับ จะพยายามใส่เพิ่มเรื่อยๆ&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;การจัดเตรียมอุปกรณ์

&lt;ul&gt;
&lt;li&gt;2.1 Softwares ทั่วไป&lt;/li&gt;
&lt;li&gt;2.2 Environment Setup
NVM (NodeJS)
การลง NodeJS โดยกำหนด Version เอง&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data types เบื้องต้น and Variables

&lt;ul&gt;
&lt;li&gt;3.1 Number&lt;/li&gt;
&lt;li&gt;3.2 String&lt;/li&gt;
&lt;li&gt;3.3 Boolean&lt;/li&gt;
&lt;li&gt;3.4 ค่ากึ่ง false&lt;/li&gt;
&lt;li&gt;3.5 Data types อื่นๆ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;if else elseif

&lt;ul&gt;
&lt;li&gt;4.1 การใช้ Terminal เบื้องต้น&lt;/li&gt;
&lt;li&gt;4.2 if condition&lt;/li&gt;
&lt;li&gt;4.3 else&lt;/li&gt;
&lt;li&gt;4.4 else if&lt;/li&gt;
&lt;li&gt;4.5 And&lt;/li&gt;
&lt;li&gt;4.6 Or&lt;/li&gt;
&lt;li&gt;4.7 Multiple And Or&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Functions

&lt;ul&gt;
&lt;li&gt;5.1 หัดสร้าง Function&lt;/li&gt;
&lt;li&gt;5.2 console.assert&lt;/li&gt;
&lt;li&gt;5.3 การส่งค่ากลับจาก Function&lt;/li&gt;
&lt;li&gt;5.4 Arrow Function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Built-in Functions

&lt;ul&gt;
&lt;li&gt;6.1 Number&lt;/li&gt;
&lt;li&gt;Number.isFinite(x)&lt;/li&gt;
&lt;li&gt;Number.parseInt(s)&lt;/li&gt;
&lt;li&gt;6.2 Math&lt;/li&gt;
&lt;li&gt;Math.pow(base, exponent)&lt;/li&gt;
&lt;li&gt;Math.abs(x)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;var let const

&lt;ul&gt;
&lt;li&gt;7.1 var&lt;/li&gt;
&lt;li&gt;7.2 let&lt;/li&gt;
&lt;li&gt;7.3 const&lt;/li&gt;
&lt;li&gt;7.4 using variable with function&lt;/li&gt;
&lt;li&gt;7.5 Arrow function usage&lt;/li&gt;
&lt;li&gt;7.6 Reserve Words&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Objects / Array

&lt;ul&gt;
&lt;li&gt;8.1 Object&lt;/li&gt;
&lt;li&gt;8.2 Array&lt;/li&gt;
&lt;li&gt;8.3 Array of Objects&lt;/li&gt;
&lt;li&gt;8.4 Array of anything&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For loops

&lt;ul&gt;
&lt;li&gt;9.1 Simple for loop&lt;/li&gt;
&lt;li&gt;9.2 Looping an Array&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;While loops

&lt;ul&gt;
&lt;li&gt;10.1 While Loop&lt;/li&gt;
&lt;li&gt;10.2 Do While&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;User Input

&lt;ul&gt;
&lt;li&gt;11.1 readline module&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Easy Challenges

&lt;ul&gt;
&lt;li&gt;12.1 วิธีทำแบบฝึกหัด&lt;/li&gt;
&lt;li&gt;12.2 เริ่มแบบฝึกหัด&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Date Time

&lt;ul&gt;
&lt;li&gt;13.1 Date Methods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Node Package Manager (npm)

&lt;ul&gt;
&lt;li&gt;14.1 npm init&lt;/li&gt;
&lt;li&gt;14.2 Moment JS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ไปต่อกันเถอะ&lt;/li&gt;
&lt;li&gt;Promise

&lt;ul&gt;
&lt;li&gt;16.1 resolve .then&lt;/li&gt;
&lt;li&gt;16.2 reject .catch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Async Await

&lt;ul&gt;
&lt;li&gt;17.1 Async Await&lt;/li&gt;
&lt;li&gt;17.2 resolve values&lt;/li&gt;
&lt;li&gt;17.3 reject values
try catch finally&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Looking inside array

&lt;ul&gt;
&lt;li&gt;18.1 Find using for loop&lt;/li&gt;
&lt;li&gt;18.2 Find using .filter&lt;/li&gt;
&lt;li&gt;18.3 Find using .find&lt;/li&gt;
&lt;li&gt;18.4 Pulling data from array using .map&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTML powered by Javascript&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ผมเขียนหนังสือเล่มนี้เพื่อให้ผู้ที่อยากเริ่มต้นเขียนโปรแกรมทุกคน ได้เข้าถึงการเขียนโปรแกรมได้โดยง่าย ผู้อ่านจะสามารถใช้ computer ส่วนตัวที่เป็น Windows 10 หรือ MacOS เพื่อหัดเขียนโค้ด และสามารถนำความรู้ไปต่อยอดการเขียนโปรแกรมอื่นๆได้อีกเช่น&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend Web Development :&lt;/strong&gt;&lt;br&gt;
VueJS, ReactJS, AngularJS, JQuery, etc..&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend Web Development :&lt;/strong&gt;&lt;br&gt;
Express, Meteor, Sequelize, etc..&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Others :&lt;/strong&gt;&lt;br&gt;
React-Native Mobile Application, IoT, etc..&lt;/p&gt;

&lt;p&gt;เมื่ออ่านหนังสือเล่มนี้จบแล้ว ผมหวังว่าผู้อ่านจะสามารถไปเขียนโปรแกรม VueJS/NuxtJS ต่อได้โดยศึกษาจากวีดีโอ ที่ผมทำไว้ใน&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=k20Srsf2r7k&amp;amp;list=PLXm-UJjVcJCMd24NIQTPcqHhfnK-QbPmD"&gt;Youtube Channel Vue/NuxtJS Playlist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หรือเมื่อเข้าใจวิธีเขียนโปรแกรมแล้ว ยังสามารถนำความรู้ไปต่อยอดเขียนภาษาอื่นๆได้อีกมากมาย เนื่องจากว่า Javascript นั้นมีความคล้ายกับภาษา C ซึ่งเป็นภาษาที่นำพื้นฐานไปต่อยอดได้ง่าย หากสนใจภาษา Ruby หรือ Ruby on Rails สามารถดูวีดีโอสอนฟรีได้ที่&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=CxFAU6x9gso&amp;amp;list=PLXm-UJjVcJCPxawSeVSYP1bsP_0_iMpQJ"&gt;Youtube Channel Ruby on Rails Playlist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;หวังว่าจะได้เจอโปรแกรมเมอร์หน้าใหม่เยอะขึ้นเรื่อยๆนะครับ&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Website หนังสือ&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://soontobeprogrammer.com"&gt;https://soontobeprogrammer.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Facebook Page&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/soon.to.be.programmer"&gt;https://www.facebook.com/soon.to.be.programmer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Facebook Group&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/groups/soon.to.be.programmer.book"&gt;https://www.facebook.com/groups/soon.to.be.programmer.book&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ขอบคุณครับ&lt;br&gt;
ศักดิ์&lt;/p&gt;

</description>
      <category>book</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>(｡`･д･)=o Using Kaomoji like a pro (；　・＿・) on your MacOS</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Tue, 01 Sep 2020 03:47:30 +0000</pubDate>
      <link>https://dev.to/sakko/o-kaomoji-on-your-macos-4b95</link>
      <guid>https://dev.to/sakko/o-kaomoji-on-your-macos-4b95</guid>
      <description>&lt;p&gt;Hi all　(;゜д゜)&lt;/p&gt;

&lt;p&gt;I've been using Japanese text art (Kaomoji) for over 10 years on my Mac and I thought I should share this. It's cool and it's cute.&lt;/p&gt;

&lt;p&gt;No extra app needed.&lt;/p&gt;

&lt;p&gt;All you need to do is open &lt;code&gt;System Preferences &amp;gt; Keyboard&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add Japanese Input Source and select only hiragana.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9n57acqnzhrq0752tpxh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9n57acqnzhrq0752tpxh.png" alt="Alt Text" width="780" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Text&lt;br&gt;
Press + to add new replacement&lt;br&gt;
on the left, I usually use を &lt;code&gt;wo&lt;/code&gt; then on the right (｡`･д･)=o&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiw4a5y9in6lud81ugmdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiw4a5y9in6lud81ugmdw.png" alt="Alt Text" width="780" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, in any application you can just type &lt;code&gt;wo&lt;/code&gt; then &lt;code&gt;spacebar&lt;/code&gt; and a popup will appear with list of replacements.　Hit enter to select the Kaomoji you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F59zvykqiigv8fhfib0dq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F59zvykqiigv8fhfib0dq.png" alt="Alt Text" width="520" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List of cool Kaomoji (670) &lt;br&gt;
&lt;a href="https://www.dropbox.com/s/lt8k3kki4m7ksuu/Kaomoji.txt?dl=0" rel="noopener noreferrer"&gt;Kaomoji.txt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lazy to add one by one? drag and drop this plist to your list of replacement to get everything I have now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.dropbox.com/s/q81j3xcro6loyh9/Text%20Substitutions.plist?dl=0" rel="noopener noreferrer"&gt;Text Substitution.plist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are using iphone + icloud, this will sync to iOS as well. So you can just type を &lt;code&gt;wo&lt;/code&gt; with japanese keyboard on iphone and the same list will popup.&lt;/p&gt;

&lt;p&gt;Feel free to modify it to suit your need. You may not need Japanese Input Source but I'm not sure if it will ruin your typing experience or not.&lt;/p&gt;

&lt;p&gt;Please share cool Kaomoji ч(ﾟдﾟч)クレッ！&lt;/p&gt;

</description>
      <category>text</category>
      <category>graphic</category>
      <category>font</category>
    </item>
    <item>
      <title>How I setup my Digital Ocean Ubuntu 20.04 Server?</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 18 Jun 2020 05:24:37 +0000</pubDate>
      <link>https://dev.to/sakko/how-i-setup-my-digital-ocean-ubuntu-18-04-server-323o</link>
      <guid>https://dev.to/sakko/how-i-setup-my-digital-ocean-ubuntu-18-04-server-323o</guid>
      <description>&lt;p&gt;My personal note to setup ubuntu server, my old note is in Quiver.&lt;/p&gt;

&lt;p&gt;Before creating a droplet, make sure to select the SSH-KEY that is used login to server.&lt;/p&gt;

&lt;p&gt;To generate new key, use this command and input the path you want to store the new key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating a droplet, ssh into server using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i ~/.ssh/ssh_key root@server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new user, for example &lt;code&gt;ubuntu&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adduser ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make ubuntu a sudoer so that &lt;code&gt;ubuntu&lt;/code&gt; can be used instead of &lt;code&gt;root&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usermod -aG sudo ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap user to &lt;code&gt;ubuntu&lt;/code&gt; and copy ssh public key to &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;su ubuntu
cd ~
mkdir .ssh
vim authorized_keys  # paste the ssh public key here
exit  # back to root user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;exit&lt;/code&gt; again to close this session.&lt;/p&gt;

&lt;p&gt;Try login using &lt;code&gt;ubuntu&lt;/code&gt; user. If done correctly, there should be no password prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i ~/.ssh/ssh_key ubuntu@server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;make &lt;code&gt;ubuntu&lt;/code&gt; sudo without supplying password&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo visudo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this line to the last part&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu ALL=(ALL) NOPASSWD:ALL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ctrl+x&lt;/code&gt; &lt;code&gt;y&lt;/code&gt; &lt;code&gt;enter&lt;/code&gt; to exit the editor&lt;/p&gt;

&lt;p&gt;&lt;code&gt;exit&lt;/code&gt; to close the session.&lt;/p&gt;

&lt;p&gt;SSH back in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i ~/.ssh/ssh_key ubuntu@server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run &lt;code&gt;sudo date&lt;/code&gt; there should be no password prompt.&lt;/p&gt;

&lt;p&gt;Now disable root ssh login&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change &lt;code&gt;PermitRootLogin yes&lt;/code&gt; to &lt;code&gt;PermitRootLogin no&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add a line &lt;code&gt;AllowUsers ubuntu&lt;/code&gt; to allow &lt;code&gt;ubuntu&lt;/code&gt; to login.&lt;/p&gt;

&lt;p&gt;Then restart ssh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service ssh restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;exit&lt;/code&gt; to close session again and test logging back in to server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i ~/.ssh/ssh_key ubuntu@server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: To change SSH Port from 22 to something else&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vi /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change &lt;code&gt;Port 22&lt;/code&gt; to the port you want.&lt;/p&gt;

&lt;p&gt;Restart SSH &lt;code&gt;sudo service ssh restart&lt;/code&gt; and then to SSH, use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i ~/.ssh/ssh_key root@server_ip -p PORT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done! Next, try using &lt;code&gt;ansible&lt;/code&gt; to setup other softwares.&lt;br&gt;
Also checkout firewall before using in production.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Using Let's Encrypt free SSL on Ubuntu Server and Nginx (wildcard included)</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Fri, 10 Apr 2020 07:38:03 +0000</pubDate>
      <link>https://dev.to/sakko/using-let-s-encrypt-free-ssl-on-ubuntu-server-and-nginx-wildcard-included-19pb</link>
      <guid>https://dev.to/sakko/using-let-s-encrypt-free-ssl-on-ubuntu-server-and-nginx-wildcard-included-19pb</guid>
      <description>&lt;p&gt;Hi, I'm just moving my notes from gitbook (legacy) to dev.to. I love it hear, it's markdown and it's quick. I hope you find this useful.&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;All you need is &lt;code&gt;certbot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certbot.eff.org/all-instructions"&gt;https://certbot.eff.org/all-instructions&lt;/a&gt;&lt;br&gt;
or&lt;br&gt;
&lt;a href="https://certbot.eff.org/lets-encrypt/ubuntubionic-apache.html"&gt;https://certbot.eff.org/lets-encrypt/ubuntubionic-apache.html&lt;/a&gt;&lt;br&gt;
to be more specific on Ubuntu 18.04&lt;/p&gt;

&lt;p&gt;This is the installation instructions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;software-properties-common
&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository universe
&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository ppa:certbot/certbot
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE I didn't include &lt;code&gt;python-certbot-apache&lt;/code&gt; because I like to do things on my own and I usually use Nginx.&lt;/p&gt;

&lt;h1&gt;
  
  
  For single domain
&lt;/h1&gt;

&lt;p&gt;I'm assuming you are using normal config path for nginx which should be located at &lt;code&gt;/etc/nginx/sites-enable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, we will create a new file called &lt;code&gt;/etc/nginx/sites-enable/letsencrypt.conf&lt;/code&gt; (you should create this in sites-available and symlink it to sites-enable)&lt;/p&gt;

&lt;p&gt;Now, this should be the content of &lt;code&gt;letsencrypt.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="s"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.nginx-debian.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="s"&gt;^~&lt;/span&gt; &lt;span class="n"&gt;/.well-known/acme-challenge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;allow&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;default_type&lt;/span&gt; &lt;span class="s"&gt;"text/plain"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make sure that all request on port &lt;code&gt;80&lt;/code&gt; with location &lt;code&gt;/.well-known/acme-challenge&lt;/code&gt; is served correctly.&lt;/p&gt;

&lt;p&gt;Any other path should be redirected to &lt;code&gt;443&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now you need to setup your dns for the domain you want. It should be A tag and point to this server. Note, you should change &lt;a href="http://www.example.com"&gt;www.example.com&lt;/a&gt; and x.x.x.x to your domain and server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;www.example.com     A     x.x.x.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may take awhile or a second, depends on your luck. Just test this config on &lt;a href="https://dnschecker.org/"&gt;https://dnschecker.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once dnschecker show the correct result you just need to run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot certonly --webroot -w /var/www/html -d www.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get chain and keys located here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/letsencrypt/live/www.example.com/fullchain.pem
/etc/letsencrypt/live/www.example.com/privkey.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generating &lt;code&gt;dhparams&lt;/code&gt; to use with ssl_dhparam config&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir /etc/nginx/dhparams
sudo openssl dhparam -out /etc/nginx/dhparams/dhparams.pem 2048
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example nginx config &lt;code&gt;/etc/nginx/sites-enable/www.example.com.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    ssl_prefer_server_ciphers on;

    # Add HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    client_max_body_size 20M;
    listen       443;
    server_name  www.example.com;
    root /home/ubuntu/your_app;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    ssl_dhparam /etc/nginx/dhparams/dhparams.pem; # you need to generate this if you want to use dhparam

    #prevent poodle
    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  For wildcard
&lt;/h1&gt;

&lt;p&gt;You need to run this command first (don't forget to change *.example.com to your domain)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot certonly --manual -d *.example.com --agree-tos --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get instructions on how to setup. It will tell you to setup &lt;code&gt;txt&lt;/code&gt; dns record. Once you complete setup your &lt;code&gt;txt&lt;/code&gt; dns record, you should confirm with &lt;a href="https://dnschecker.org/"&gt;https://dnschecker.org/&lt;/a&gt; before hitting enter.&lt;/p&gt;

&lt;p&gt;If nothing is wrong, you should get wildcard ssl in this path if you are using *.example.com&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You just have to setup nginx accordingly and it should be done.&lt;/p&gt;

&lt;p&gt;I'm sure there are better ways than this but this is my old note.&lt;br&gt;
If anyone have better instructions, please let me know so I can share with other as well.&lt;/p&gt;

</description>
      <category>letsencrypt</category>
      <category>server</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>สอน VueJS / NuxtJS / Javascript วีดีโอ ตั้งแต่เตรียมเครื่อง ยันเขียนเป็น</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Thu, 09 Apr 2020 09:53:37 +0000</pubDate>
      <link>https://dev.to/sakko/vuejs-nuxtjs-571o</link>
      <guid>https://dev.to/sakko/vuejs-nuxtjs-571o</guid>
      <description>&lt;p&gt;สวัสดีครับ ผมศักดิ์ เปิดบริษัท Softwarehouse มากว่า 10 ปี ประสบการณ์ด้าน Programming 10 ปี รับเขียนโปรแกรมมามากมายหลายภาษา/Framework ครับ&lt;/p&gt;

&lt;p&gt;สำหรับคนที่พึ่งเริ่มเขียนโปรแกรมแบบไม่มีพื้นฐาน ผมแนะนำให้ลองอ่านหนังสือที่ผมแต่งเองขึ้นมา สำหรับผู้เริ่มต้นก่อนนะครับ ช่วยอุดหนุนหน่อยครับ&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/soon-to-be-programmer" rel="noopener noreferrer"&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%2F0631t35n384uh23bve1e.png" alt="เกิดอยากจะเป็นโปรแกรมเมอร์"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/soon-to-be-programmer" rel="noopener noreferrer"&gt;กดที่นี่เพื่อเข้าไปซื้อหนังสือครับ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ผมพยายามทำและรวบรวมวีดีโอที่ผมทำเอง และ ถ้าเป็นไปได้จะพยายามเอาวีดีโออื่นๆที่เกี่ยวข้องมารวมด้วยครับ (ข้ามไปดูวีดีโอด้านล่างสุดได้เลยครับ สำหรับคนใจร้อน)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UC1Jindq-cR4nryXJF2gybbQ?sub_confirmation=1&amp;amp;fbclid=IwAR2hQSaMSUnXp-9uIjFkSSdSucovYHenEOmIpRBnAfyX_yFH5PWO-zSLmQM" rel="noopener noreferrer"&gt;Youtube Channel SaKKosama 🐶 กดติดตามหน่อยนะครับ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เป้าหมายคือ อยากให้เป็นประโยชน์กับทุกๆคน ไม่ว่าจะพนักงานของผมเอง หรือ จะเป็นคนที่มีความสนใจศึกษา VueJS / NuxtJS และอยากให้มี Developer ชาวไทยเยอะขึ้นครับ&lt;/p&gt;

&lt;p&gt;List ข้อดีของ VueJS + NuxtJS&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;เขียนง่าย เขียนเร็ว ขอแค่เขียน Javascipt เป็น&lt;/li&gt;
&lt;li&gt;Support SSR, SPA, PWA&lt;/li&gt;
&lt;li&gt;ไม่ต้องเขียน JSX แต่จะเขียนก็ได้&lt;/li&gt;
&lt;li&gt;Library / Components ช่วยเยอะแยะมากมาย&lt;/li&gt;
&lt;li&gt;Doc อ่านเข้าใจง่ายมาก&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;แถมนิดนึงสำหรับคนอยาก deploy nuxtjs โดยใช้ Google Cloud Run (Serverless ครับ)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/sakko/deploying-nuxtjs-on-google-cloud-run-1fic"&gt;Deploying Nuxtjs on Google Cloud Run (Serverless)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;วีดีโอเริ่มต้นครับ สำหรับคนได้เครื่องใหม่มา หรือว่าอยาก clean up เครื่อง&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/sakko/how-i-upgrade-my-mac-for-development-in-catalina-macos-33g1"&gt;วิธีเตรียม MACOS Catalina จากเครื่องใหม่ จนพร้อมใช้งาน&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=k20Srsf2r7k" rel="noopener noreferrer"&gt;วิธีเตรียมเครื่องสำหรับ NodeJS อย่างเดียว&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/DA4csMg7XqM" rel="noopener noreferrer"&gt;สอนลง NodeJS บน Windows 10 ด้วย NVM สลับ Version Node ได้ไม่จำกัด&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;วีดีโอ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLXm-UJjVcJCMd24NIQTPcqHhfnK-QbPmD" rel="noopener noreferrer"&gt;Full Playlist ครับ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;แยกร่างครับ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/NcqZjTg_1PI" rel="noopener noreferrer"&gt;Nuxt+Vue EP1: Creating NuxtJS Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/aPVAncMcBCM" rel="noopener noreferrer"&gt;Nuxt+Vue EP1.1: Atom Text editor guide (มือใหม่ต้องดูครับ)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/pBMbQLIY1zA" rel="noopener noreferrer"&gt;Nuxt+Vue EP2: Basic VueJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/4Ihi506N_6M" rel="noopener noreferrer"&gt;Nuxt+Vue EP3: Creating Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/VJlvILjcGQI" rel="noopener noreferrer"&gt;Nuxt+Vue EP4: Vue Instance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/m4kLme7Tl4s" rel="noopener noreferrer"&gt;Nuxt+Vue EP5: Vue Template Syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/fz79jFIUuE4" rel="noopener noreferrer"&gt;Nuxt+Vue EP6: Compute and Methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/iztFcYxqo8E" rel="noopener noreferrer"&gt;Nuxt+Vue EP7: Vue Watch + NuxtJS install/import library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/wsuUlMoEmlA" rel="noopener noreferrer"&gt;Nuxt+Vue EP8: Adding Class and Styles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/zDZOZN2BOe0" rel="noopener noreferrer"&gt;Nuxt+Vue EP9: $EMIT, Listen to component custom events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/qDTFK4tKfpU" rel="noopener noreferrer"&gt;Nuxt+Vue EP10: Call API + Vuetify Framework on NuxtJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/IxWebuaHAjg" rel="noopener noreferrer"&gt;Nuxt+Vue EP10.1: Call API + iView UI Framework on NuxtJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/CrSG2GcW2HQ" rel="noopener noreferrer"&gt;Nuxt+Vue EP11: Nuxt Route, vue-router, Named route (Vuetify)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/EbyWKAak2MU" rel="noopener noreferrer"&gt;Nuxt+Vue EP12: Javascript Async Await&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/pd96dsgjAXo" rel="noopener noreferrer"&gt;Nuxt+Vue EP13: Nuxt Store, Vuex, Vuetify Drawer State&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/V-5tnxu7HBI" rel="noopener noreferrer"&gt;Nuxt+Vue EP14: Vuetify Layout Tutorial (Clean up code)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/2DwdzXyYJo4" rel="noopener noreferrer"&gt;Nuxt+Vue EP15: Workshop - Nuxt Auth Login and Vuetify preparation for CRUD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/0xeJpQik9Kg" rel="noopener noreferrer"&gt;Nuxt+Vue EP16: Workshop - CRUD+REST API after Login&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/P5s0DRSbqug" rel="noopener noreferrer"&gt;สร้าง API EP15,EP16 ด้วย Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/b0_9A7jBD-c" rel="noopener noreferrer"&gt;Nuxt+Vue EP17: Import Components &amp;amp;&amp;amp; Plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/h2aBakYfirI" rel="noopener noreferrer"&gt;Nuxt+Vue EP18: How to use asyncData?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/V-IrHn9e5fY" rel="noopener noreferrer"&gt;Nuxt+Vue EP19: How to use fetch?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/y6DMjz_eKtk" rel="noopener noreferrer"&gt;Nuxt+Vue EP20: Create Card Component and Using Vue Slots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/jeFGAnxpuz0" rel="noopener noreferrer"&gt;Nuxt+Vue EP21: Add Global Configs / Settings to Nuxtjs ENV&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;วิธี deploy NuxtJS ไป Google Cloud Run ครับ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=pFQxDS5Uamo&amp;amp;list=PLXm-UJjVcJCMd24NIQTPcqHhfnK-QbPmD&amp;amp;index=23&amp;amp;fbclid=IwAR3q_-akG0PpEshkuzoA4wlJVLgT689S1JZyZb8i40nS3FxmHFE6BXXXV6k" rel="noopener noreferrer"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=mNJ0HLU4dWw&amp;amp;list=PLXm-UJjVcJCMd24NIQTPcqHhfnK-QbPmD&amp;amp;index=24&amp;amp;fbclid=IwAR21dNbrTC04tS-HOcN3Y-Nq2UvzNEsfhBKPNNtu6TI_XTAA29EeiBZfjGc" rel="noopener noreferrer"&gt;ลงทะเบียน Google Cloud Platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=cogW9M4s68E&amp;amp;list=PLXm-UJjVcJCMd24NIQTPcqHhfnK-QbPmD&amp;amp;index=25&amp;amp;fbclid=IwAR0pfj34GS62UI-nJ11VKZM9mxEe6scsmD6wlYhALD1q-a-tvkGCfeDnxg4" rel="noopener noreferrer"&gt;ลง Google Cloud CLI / Login ผ่าน Command Line (ต้องทำนะครับ)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=8Pq79ZQ1r-E&amp;amp;list=PLXm-UJjVcJCMd24NIQTPcqHhfnK-QbPmD&amp;amp;index=26&amp;amp;fbclid=IwAR1_gb7rXInhiyX5ei8UBZ-klQeRH6PU7jymwknzd-u0ThQAYOJJrjbRxtI" rel="noopener noreferrer"&gt;สร้าง Nuxt Project, Dockerfile, Cloud-build, และ deploy ไป Cloud run&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>thai</category>
    </item>
    <item>
      <title>หนังสือ/ebook/วีดีโอ สอน Ruby on Rails สร้าง API ตั้งแต่เตรียมเครื่อง ยันเขียนเป็น</title>
      <dc:creator>SaKKo</dc:creator>
      <pubDate>Mon, 27 Jan 2020 05:40:14 +0000</pubDate>
      <link>https://dev.to/sakko/ruby-on-rails-ha8</link>
      <guid>https://dev.to/sakko/ruby-on-rails-ha8</guid>
      <description>&lt;p&gt;Test&lt;/p&gt;

&lt;p&gt;สวัสดีครับ ผมศักดิ์ เปิดบริษัท Softwarehouse มากว่า 10 ปี ใช้ Ruby on Rails มาประมาน 8 ปี รับเขียนโปรแกรมมามากมายหลายภาษา/Framework ครับ&lt;/p&gt;

&lt;p&gt;ข้อมูลอื่นๆเกี่ยวกับหนังสือ สามารถดูได้ที่&lt;br&gt;
&lt;a href="https://soontobeprogrammer.com"&gt;soontobeprogrammer.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ผมแต่งหนังสือเสร็จแล้วครับ
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://sakko.dev/ror-book"&gt;กดที่นี่เพื่อซื้อหนังสือผ่าน shopee&lt;/a&gt;&lt;br&gt;
&lt;a href="https://sakko.dev/ror-ebook"&gt;กดที่นี่เพื่อซื่อ ebook ผ่าน Leanpub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uUCoWnP8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://soontobeprogrammer.com/books/ror/toc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uUCoWnP8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://soontobeprogrammer.com/books/ror/toc.png" alt="เกิดอยากจะเป็นโปรแกรมเมอร์ สารบัญ" width="880" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เนื้อหาของหนังสือมีดังนี้ครับ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;บทท่ี 1 - เตรียมเครื่อง

&lt;ul&gt;
&lt;li&gt;rvm / Install Ruby&lt;/li&gt;
&lt;li&gt;nvm / Install NodeJS (optional) Ruby on Rails&lt;/li&gt;
&lt;li&gt;Text Editor&lt;/li&gt;
&lt;li&gt;Postman / Hoppscoth&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 2 - สร้าง Project&lt;/li&gt;
&lt;li&gt;บทท่ี 3 - Folders และ Files

&lt;ul&gt;
&lt;li&gt;root Folder&lt;/li&gt;
&lt;li&gt;config Folder&lt;/li&gt;
&lt;li&gt;app Folder&lt;/li&gt;
&lt;li&gt;Files อื่นๆ&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 4 - ภาษา Ruby

&lt;ul&gt;
&lt;li&gt;Numbers&lt;/li&gt;
&lt;li&gt;String&lt;/li&gt;
&lt;li&gt;Comment&lt;/li&gt;
&lt;li&gt;puts และ print&lt;/li&gt;
&lt;li&gt;Array&lt;/li&gt;
&lt;li&gt;Hash&lt;/li&gt;
&lt;li&gt;if / else / elsif / end&lt;/li&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;li&gt;Case (switch)&lt;/li&gt;
&lt;li&gt;Loops (for ,while, each)&lt;/li&gt;
&lt;li&gt;map&lt;/li&gt;
&lt;li&gt;implicit / explicit return&lt;/li&gt;
&lt;li&gt;Code Block 30 Class / Object&lt;/li&gt;
&lt;li&gt;Subclass&lt;/li&gt;
&lt;li&gt;Modify Build-in Class&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 5 - Controllers

&lt;ul&gt;
&lt;li&gt;Static API [GET]&lt;/li&gt;
&lt;li&gt;Request with curl&lt;/li&gt;
&lt;li&gt;CORs / Hoppscotch&lt;/li&gt;
&lt;li&gt;POST/PUT/PATCH/DELETE&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 6 - Model / Database

&lt;ul&gt;
&lt;li&gt;ActiveRecord&lt;/li&gt;
&lt;li&gt;Model / Table Design&lt;/li&gt;
&lt;li&gt;Code First Database Migration&lt;/li&gt;
&lt;li&gt;การแก้ไขโครงสร้าง Database&lt;/li&gt;
&lt;li&gt;การเขียนข้อมูลด้วย Rails Console&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 7 - CRUD REST API

&lt;ul&gt;
&lt;li&gt;New project&lt;/li&gt;
&lt;li&gt;REST APIs&lt;/li&gt;
&lt;li&gt;Generating Controllers&lt;/li&gt;
&lt;li&gt;GET users#index&lt;/li&gt;
&lt;li&gt;POST users#create&lt;/li&gt;
&lt;li&gt;GET users#show&lt;/li&gt;
&lt;li&gt;PUT/PATCH users#update&lt;/li&gt;
&lt;li&gt;DELETE users#destroy&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 8 - Scaffolding

&lt;ul&gt;
&lt;li&gt;rails g scaffold&lt;/li&gt;
&lt;li&gt;ทดสอบ API จาก scaffold&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 9 - Model Relationships

&lt;ul&gt;
&lt;li&gt;Defining Relationships&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 10 - Sending Emails

&lt;ul&gt;
&lt;li&gt;Mailgun&lt;/li&gt;
&lt;li&gt;ActionMailer Basic&lt;/li&gt;
&lt;li&gt;Sending Real emails&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 11 - Errors Handling

&lt;ul&gt;
&lt;li&gt;rescue&lt;/li&gt;
&lt;li&gt;throwing errors&lt;/li&gt;
&lt;li&gt;Custom Error Class&lt;/li&gt;
&lt;li&gt;Catching Errors in Controller&lt;/li&gt;
&lt;li&gt;Other errors to rescue&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 12 - Authenticating APIs

&lt;ul&gt;
&lt;li&gt;devise gem&lt;/li&gt;
&lt;li&gt;JWT&lt;/li&gt;
&lt;li&gt;Model callbacks&lt;/li&gt;
&lt;li&gt;Sessions Controller&lt;/li&gt;
&lt;li&gt;Sign up API&lt;/li&gt;
&lt;li&gt;Sign in API&lt;/li&gt;
&lt;li&gt;Profile API&lt;/li&gt;
&lt;li&gt;Sign out API&lt;/li&gt;
&lt;li&gt;Catching JWT / API Errors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 13 - Model Validation

&lt;ul&gt;
&lt;li&gt;Presence&lt;/li&gt;
&lt;li&gt;Inclusion&lt;/li&gt;
&lt;li&gt;Length / Number&lt;/li&gt;
&lt;li&gt;Custom Validation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 14 - Query Interfaces

&lt;ul&gt;
&lt;li&gt;.find / .find*by*?&lt;/li&gt;
&lt;li&gt;.where / .where.not&lt;/li&gt;
&lt;li&gt;Date Query&lt;/li&gt;
&lt;li&gt;Scope&lt;/li&gt;
&lt;li&gt;Scope with function&lt;/li&gt;
&lt;li&gt;Ordering&lt;/li&gt;
&lt;li&gt;Readonly Object&lt;/li&gt;
&lt;li&gt;JOIN&lt;/li&gt;
&lt;li&gt;Eager Load / N+1 Query&lt;/li&gt;
&lt;li&gt;Selecting Fields to Query&lt;/li&gt;
&lt;li&gt;Calculations&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 15 - Caching with Rails

&lt;ul&gt;
&lt;li&gt;Installing REDIS&lt;/li&gt;
&lt;li&gt;Configuring Rails&lt;/li&gt;
&lt;li&gt;Simple Cache Key&lt;/li&gt;
&lt;li&gt;Caching Model&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 16 - Delayed Jobs

&lt;ul&gt;
&lt;li&gt;ActiveJob&lt;/li&gt;
&lt;li&gt;Using with Mailer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 17 - Uploading files / Images

&lt;ul&gt;
&lt;li&gt;ActiveStorage&lt;/li&gt;
&lt;li&gt;Upload Image API&lt;/li&gt;
&lt;li&gt;multipart/form-data&lt;/li&gt;
&lt;li&gt;Auto Resize Images&lt;/li&gt;
&lt;li&gt;File Validation&lt;/li&gt;
&lt;li&gt;Storage Config&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 18 - Model / State Machine

&lt;ul&gt;
&lt;li&gt;AASM&lt;/li&gt;
&lt;li&gt;States&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Callbacks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 19 - Unit Test

&lt;ul&gt;
&lt;li&gt;Rails test&lt;/li&gt;
&lt;li&gt;Test Driven Development (TDD)&lt;/li&gt;
&lt;li&gt;Fixtures&lt;/li&gt;
&lt;li&gt;Parallels Testing&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 20 - Searching Database

&lt;ul&gt;
&lt;li&gt;Preparation / Database Seed&lt;/li&gt;
&lt;li&gt;SQL Search / Ransack&lt;/li&gt;
&lt;li&gt;SQL Multi-column Ransack&lt;/li&gt;
&lt;li&gt;ElasticSearch / Searchkick&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทที 21 - Security / Credentials

&lt;ul&gt;
&lt;li&gt;rails credentials&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;บทท่ี 22 - Deploying Rails

&lt;ul&gt;
&lt;li&gt;Server Preparation (Ubuntu)&lt;/li&gt;
&lt;li&gt;Adding new user to Server&lt;/li&gt;
&lt;li&gt;Installing Rails / NGINX&lt;/li&gt;
&lt;li&gt;Deploying Code&lt;/li&gt;
&lt;li&gt;Nginx &amp;amp; Passenger Config&lt;/li&gt;
&lt;li&gt;SSL / Let’s Encrypt Config&lt;/li&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  สำหรับ Video
&lt;/h2&gt;

&lt;p&gt;ผมพยายามทำและรวบรวมวีดีโอที่ผมทำเอง และ ถ้าเป็นไปได้จะพยายามเอาวีดีโออื่นๆที่เกี่ยวข้องมารวมด้วยครับ (ข้ามไปดูวีดีโอด้านล่างสุดได้เลยครับ สำหรับคนใจร้อน)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UC1Jindq-cR4nryXJF2gybbQ?sub_confirmation=1&amp;amp;fbclid=IwAR2hQSaMSUnXp-9uIjFkSSdSucovYHenEOmIpRBnAfyX_yFH5PWO-zSLmQM"&gt;Youtube Channel SaKKosama 🐶 กดติดตามหน่อยนะครับ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เป้าหมายคือ อยากให้เป็นประโยชน์กับทุกๆคน ไม่ว่าจะพนักงานของผมเอง หรือ จะเป็นคนที่มีความสนใจศึกษา Ruby on Rails และอยากให้มี Developer ชาวไทยหันมาใช้งาน Ruby on Rails กันให้เยอะขึ้นครับ&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;ปล. Web dev.to นี้ก็เขียนด้วย Ruby on Rails นะครับ&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;List ข้อดีของ Ruby on Rails&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ruby เป็นภาษาที่ สามารถอ่านได้ง่าย เข้าใจง่าย&lt;/li&gt;
&lt;li&gt;Rails เป็น Framework ที่มี High standard และ Convention ที่ดีมากๆ ดีขนาดที่ทุกๆ Framework พยายามนำไปเปรียบเทียบ&lt;/li&gt;
&lt;li&gt;คนชอบบอกว่า High Learning Curve แต่สำหรับผม มันขึ้นอยู่กับว่า เริ่มอย่างไรมากกว่า&lt;/li&gt;
&lt;li&gt;Rails เป็น Framework ที่มีครบเกือบจะทุกอย่างที่ Developer ต้องการสำหรับ Web Development&lt;/li&gt;
&lt;li&gt;Rails เป็น Framework ที่ทำให้สามารถพัฒนาระบบอะไรก็ตามได้อย่างรวดเร็ว และ สามารถทำการเปลี่ยนแปลง feature ต่างๆ ได้โดยง่าย&lt;/li&gt;
&lt;li&gt;Rails ตั้งแต่ Rails 5 ขึ้นมา มีการใส่ Test Driven Development ได้โดยง่าย ไม่ว่าจะเป็น Unit test, Integration test ในทุกๆเรื่อง โดยที่มีการกำหนดวิธีเขียนมี standard อย่างชัดเจน&lt;/li&gt;
&lt;li&gt;Rails มี Security Standard ที่ชัดเจน หากทำตามที่ Framework กำหนด มีความปลอดภัยในการทำสูงมาก&lt;/li&gt;
&lt;li&gt;Rails caching mechanism ดีมากๆ ไม่ว่าจะเป็น Query Cache, Redis Cache รับรองว่าใช้แล้วจะแปลกใจทำไมภาษาอื่นไม่มี&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;List ข้อด้อยของ Ruby on Rails ที่คนชอบบ่นกัน&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;หลักๆเลยคือ ช้า... คนบ่นทุกคน แต่มันก็พอๆกะ Python (Django)&lt;/li&gt;
&lt;li&gt;Scale ยาก เพราะว่ามันช้า มันเลย Require scaling เยอะกว่าคนอื่น&lt;/li&gt;
&lt;li&gt;พึ่งพา gem เยอะ และอาจจะทำให้ไม่ค่อย Flexible หากเลือกไม่ดี (เป็นเหมือนกันทุกภาษา)&lt;/li&gt;
&lt;li&gt;Learning curve / Learning Material เอาจริงๆ ผมว่าขึ้นอยู่กะคน&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;สรุปความคิดเห็นส่วนตัว&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ภาษาที่เขียนง่าย อ่านง่าย จะทำให้ Maintain ง่ายขึ้น ผมเปิดบริษัทมาร่วมสิบปี Maintain Rails เป็นอะไรที่สบายที่สุด แต่ NodeJS เป็นอะไรที่ทรมานที่สุด &lt;/li&gt;
&lt;li&gt;ภาษาที่เขียนง่าย ทำให้สามารถเขียน function ยากๆได้ง่ายขึ้น ภาษาที่เร็วๆ เขียนไม่ดีมันก็ช้าได้&lt;/li&gt;
&lt;li&gt;Function ไหนอยากให้เร็วขึ้น

&lt;ul&gt;
&lt;li&gt;หาทางทำ Caching&lt;/li&gt;
&lt;li&gt;Optimize query&lt;/li&gt;
&lt;li&gt;ย้ายไปทำ Microservice แยก เอาก็ได้&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;พิมมาเยอะ ใครเห็นด้วยไม่เห็นด้วยก็ติชมได้ครับ จะพยายามปรับให้ดีขึ้นเรื่อยๆครับ&lt;br&gt;
ขอบคุณครับ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/sakko/how-i-upgrade-my-mac-for-development-in-catalina-macos-33g1"&gt;วิธีเตรียม MACOS Catalina จากเครื่องใหม่ จนพร้อมใช้งาน&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;วิีดีโอ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://youtu.be/UxGriOptHp4"&gt;TIPS EP0: เตรียม server Ubuntu Server 18.04 แบบง่ายๆ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/HuS7ExxszBo"&gt;Ruby on Rails EP1: สอน Ruby on Rails (Active Record / Models)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/eVoom6bFLnA"&gt;Ruby on Rails EP2: สอน Ruby on Rails (Model / has_many)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/_V0gjIFHXOI"&gt;Ruby on Rails EP3: สอน Ruby on Rails (Models / many to many)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/KDeVepjQoMA"&gt;Ruby on Rails EP4: สอน Ruby on Rails (routes)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/uZsWOlWSPpE"&gt;Ruby on Rails EP5: สอน Ruby on Rails (Routes and APIs)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/QYmwWi34x4U"&gt;Ruby on Rails EP5.1 สอน Ruby on Rails (Routes and APIs ต่อ)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/f6M-vCsh-j8"&gt;Ruby on Rails EP6: สอน Ruby on Rails (Scaffolding)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/eBUDY_2YfHY"&gt;Ruby on Rails EP7: สอน Ruby on Rails (Active Record Callbacks)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/OX9NZVpSqRk"&gt;Ruby on Rails EP8: สอน Ruby on Rails (ActiveRecord State Machine)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/hCA6KrA8GTI"&gt;Ruby on Rails EP9: สอน Ruby on Rails (Make APIs Rescue from any Error)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/FiFlwATdYxA"&gt;Ruby on Rails EP10: สอน Ruby on Rails (ใช้ credentials กับ สร้าง JWT)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/9fhO6yTYkzM"&gt;Ruby on Rails EP11: Active Record (Single Table Inheritance)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/mhUxliEt_i0"&gt;Ruby on Rails Ep12: Rails powered by Ruby (พื้นฐาน Ruby #1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/gI01wZrBzFI"&gt;Ruby on Rails Ep12.1: Rails powered by Ruby (พื้นฐาน Ruby #2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/EWzRwCdd5aM"&gt;Ruby on Rails Ep12.2: Rails powered by Ruby (พื้นฐาน Ruby #3 Class)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/64Gd1S29R3E"&gt;Ruby on Rails Ep13: Polymorphic using Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/P5s0DRSbqug"&gt;Ruby on Rails EP14: Workshop Login API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/U03cupzUf4U"&gt;Ruby on Rails EP14.1: Workshop Rest API CRUD (cont.)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/2DwdzXyYJo4"&gt;เขียน NuxtJS+VueJS มาเชื่อมต่อ EP14,EP14,1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/nY7i_KwmjSU"&gt;เทคนิค Code First Database Migration สร้าง Database ด้วย Code แบบแทบจะไม่ต้องพึ่ง SQL อีกเลย&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>thai</category>
    </item>
  </channel>
</rss>
