<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Jimmy Cheung on Medium]]></title>
        <description><![CDATA[Stories by Jimmy Cheung on Medium]]></description>
        <link>https://medium.com/@jhcheung?source=rss-df62cd40ab78------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*njMMNGXlOLlLw7_q.jpg</url>
            <title>Stories by Jimmy Cheung on Medium</title>
            <link>https://medium.com/@jhcheung?source=rss-df62cd40ab78------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 01:48:56 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jhcheung/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Reading and writing JSONs in Ruby]]></title>
            <link>https://jhcheung.medium.com/reading-and-writing-jsons-in-ruby-d58d01392bef?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/d58d01392bef</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Sun, 25 Oct 2020 22:49:13 GMT</pubDate>
            <atom:updated>2020-10-25T22:49:13.031Z</atom:updated>
            <content:encoded><![CDATA[<p>Ruby has some built in functionality to read files and some outside functionality to parse JSONs that can come in handy.</p><h3>File.read</h3><p>The File class in Ruby has a bunch of different methods for handling files and checking on files. The relevant one here is the ‘open’ method.</p><pre>file = File.read(&#39;db/items.json&#39;)</pre><p>This will translate the file to be read in Ruby and save it to a variable</p><h3>JSON.parse</h3><p>The JSON library is not a built in feature in Ruby and so must be added as a requirement.</p><pre>require &#39;json&#39;</pre><pre>items_json = JSON.parse(file)</pre><p>Building on the previous code, you are able to then use the JSON parse method to read the file. What is then produced is a Ruby hash of the existing JSON file.</p><h3>File.open</h3><p>We can also write new JSON files using File and JSON together.</p><p>The File.open function will open the file requested. The “w” argument will open it in write mode. Then, the inner block will write the hash to the file. The JSON.pretty_generate function also cleans up the hash to better fit JSON standards. Please note that this will rewrite the current file contents with the contents of the hash variable.</p><pre>require &#39;json&#39;<br>hash = {<br>    &quot;a&quot; =&gt; &quot;A&quot;,<br>    &quot;b&quot; =&gt; &quot;B&quot;<br>}<br>File.open(&quot;db/items.json&quot;,&quot;w&quot;) do |f|<br>  f.write(JSON.pretty_generate(hash))<br>end</pre><h3>Sources</h3><ul><li><a href="https://ruby-doc.org/core-2.5.0/File.html#method-c-open">File</a></li><li><a href="https://ruby-doc.org/stdlib-2.7.2/libdoc/json/rdoc/JSON.html">JSON</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d58d01392bef" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using websockets (ActionCable) with Rails app: Part 2 (React frontend)]]></title>
            <link>https://jhcheung.medium.com/using-websockets-actioncable-with-rails-app-part-2-react-frontend-64d6087a3886?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/64d6087a3886</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 19 Oct 2020 03:46:15 GMT</pubDate>
            <atom:updated>2020-10-19T03:46:15.745Z</atom:updated>
            <content:encoded><![CDATA[<p>In <a href="https://medium.com/@jhcheung/using-websockets-actioncable-with-rails-app-cab09a35902a">my first article</a>, I covered the basics of setting up Rails to use ActionCable. Now, you can use ActionCable with a React frontend as well.</p><h3>What you need</h3><p>React</p><p>Rails</p><p><a href="https://github.com/JackHowa/react-actioncable-provider">React ActionCable Provider</a></p><h3>Instructions</h3><ol><li>Set up the ActionCable as described in the previous article.</li><li>Install react-actioncable-provider using the following commands</li></ol><pre>npm install --save @thrash-industries/react-actioncable-provider</pre><p>3. In your React frontend, wrap the &lt;App /&gt; component in the ActionCable Provider code:</p><pre>import { ActionCableProvider } from &#39;react-actioncable-provider&#39;;<br><br><br>&lt;ActionCableProvider url=&#39;ws://localhost:3001/cable&#39;&gt;<br>  &lt;App /&gt;<br>&lt;/ActionCableProvider&gt;</pre><p>4. In the component itself where you wish to receive ActionCable subscriptions, wrap the component in the Action Cable Consumer code:</p><pre>import { ActionCableConsumer } from &#39;react-actioncable-provider&#39;;<br><br>	&lt;ActionCableConsumer<br>    channel={{ channel: &#39;&#39; }}<br>    onReceived={}<br>  /&gt;</pre><p>For the channel name, use the channel that you wish to subscribe to. The onReceived property can be used with a function that you run on the data that is received from the ActionCable channel.</p><h3>Conclusion</h3><p>Integrating React with ActionCable is relatively simple. Now, you can broadcast from your Rails app (using the instructions in the previous article), and then receive it in your React component to render.</p><h3>Sources</h3><p><a href="https://github.com/ihollander/actioncable-starter-app">https://github.com/ihollander/actioncable-starter-app</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=64d6087a3886" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using websockets (ActionCable) with Rails app]]></title>
            <link>https://jhcheung.medium.com/using-websockets-actioncable-with-rails-app-cab09a35902a?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/cab09a35902a</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 12 Oct 2020 03:18:17 GMT</pubDate>
            <atom:updated>2020-10-19T02:55:02.193Z</atom:updated>
            <content:encoded><![CDATA[<p>Websockets are a flexible communications protocol (similar to http) that allows developers to create duplex communications in their web apps. For example, HTTP allows for delivery of data from the server to the client, but generally only when the client sends a request to the server. With websockets, and the ws:// protocol, servers can also poll for clients to send data at specific times. This allows for real time update of content, such as with chat applications or live news feeds.</p><h3>ActionCable History</h3><p>Enter ActionCable. ActionCable was released with Rails 5 and was a relatively late addition of websockets to the Rails tech stack. There was previously no websocket support, with only third party libraries and Javascript workarounds. Now, with your modern Rails installation, you should ActionCable ready to go with some simple tweaks.</p><h3>Starting with ActionCable</h3><ol><li>Making an ActionCable route.</li></ol><p>First, you set up an ActionCable route by adding the following code to your ‘routes.rb’ file:</p><pre>mount ActionCable.server =&gt; &#39;/cable&#39;</pre><p>2. Make a channel for your data feed. You can use the default rails generator for this:</p><pre>rails g channel messages</pre><p>In the sample code I am presenting, we are creating an ActionCable implementation of a messaging app.</p><p>The above generator will generate the following channel code:</p><pre>class MessagesChannel &lt; ApplicationCable::Channel</pre><pre>def subscribed</pre><pre>def unsubscribed</pre><pre># Any cleanup needed when channel is unsubscribed</pre><pre>end</pre><pre>end</pre><p>3. After creating that channel, you will now have to access it from your client. This is done by default in Rails in the consumer.js Javascript file</p><pre>// app/javascript/channels/consumer.js<br>// Action Cable provides the framework to deal with WebSockets in Rails.<br>// You can generate new channels where WebSocket features live using the `rails generate channel` command.<br> <br>import { createConsumer } from &quot;<a href="http://twitter.com/rails/actioncable">@rails/actioncable</a>&quot;<br> <br>export default createConsumer()</pre><p>Then, to connect to specific channels, you can utilize this code, which will subscribe your Rails app to the requested channel.</p><pre>// app/javascript/channels/messages_channel.js<br>import consumer from &quot;./consumer&quot;<br> <br>consumer.subscriptions.create({ channel: &quot;MessagesChannel&quot;, room: &quot;Best Room&quot; })</pre><p>4. The last part of utilizing ActionCable is to broadcast to the channel in question. You would normally do this in another part of the Rails app.</p><pre>MessagesChannel.broadcast_to(<br>  current_user,<br>  title: &#39;New things!&#39;,<br>  body: &#39;All the news fit to print&#39;<br>)</pre><h3>Conclusion</h3><p>This is a description of the basic components of using ActionCable with your Rails app. It has definitely been simplified from past implementations without Action Cable, and shows the basic core loop of the ActionCable implementation, where you have subscriptions to a channel you set up, then subscribe to the channel from the consumer, and then lastly broadcast to the channel from the Rails app to provide data to the consumers.</p><h3>Sources</h3><p><a href="https://guides.rubyonrails.org/action_cable_overview.html">Action Cable Overview - Ruby on Rails Guides</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cab09a35902a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using ActiveStorage with your Rails app]]></title>
            <link>https://jhcheung.medium.com/using-activestorage-with-your-rails-app-bb699d77cefe?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/bb699d77cefe</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 05 Oct 2020 03:32:58 GMT</pubDate>
            <atom:updated>2020-10-05T03:32:58.256Z</atom:updated>
            <content:encoded><![CDATA[<p>When you use images with your Rails app, you can do it in several different ways. One way is easy — just put your images in the ‘app/assets/images’ directory. Then, you can utilize the Rails asset pipeline to access your image. But what if you want to do more with your images? What if you want to use Amazon AWS, Microsoft Azure, or Google Cloud Storage to store your images? Then, you can use Active Storage.</p><h3>Active Storage Setup</h3><p>First, run these two commands to set up Active Storage in your Rails app:</p><pre>bin/rails active_storage:install<br>bin/rails db:migrate</pre><p>This will generate and migrate the database required for the storage of these images.</p><p>Then, you can configure the ‘config/storage.yml’ file. If you have access to cloud services of any sort, you can set them up here with access keys:</p><pre>local:<br>  service: Disk<br>  root: &lt;%= Rails.root.join(&quot;storage&quot;) %&gt;<br><br>test:<br>  service: Disk<br>  root: &lt;%= Rails.root.join(&quot;tmp/storage&quot;) %&gt;<br><br>amazon:<br>  service: S3<br>  access_key_id: &quot;&quot;<br>  secret_access_key: &quot;&quot;<br>  bucket: &quot;&quot;<br>  region: &quot;&quot; # e.g. &#39;us-east-1&#39;</pre><p>Then, you can change the setting of your environment ‘config/environments/development.rb’ to tell your rails app which service to use. To begin with, stick with local.</p><pre>config.active_storage.service = :local</pre><p>You can change this to use one of the other configs you set up in storage.yml.</p><h3>Setting up the model</h3><p>Now, in your models in ActiveRecord, you can now use the ‘has_one_attached’ macro to ensure each User can be associated with an image.</p><pre>class User &lt; ApplicationRecord<br>  has_one_attached :avatar<br>end</pre><p>If you require multiple images, you can use ‘has_many_attached’ instead.</p><pre>class Message &lt; ApplicationRecord<br>  has_many_attached :images<br>end</pre><h3>Using Active Storage for submitted images</h3><p>Now that you have ActiveStorage set up with you models, you can begin with a couple ways of how to use ActiveStorage. One of the most common ways is to allow someone to upload images. To do so, simply put on your Rails web page a request for the file_field in question:</p><pre>&lt;%= form.file_field :avatar %&gt;</pre><p>Then, in your Rails code, you can call upon the ‘attach’ method to attach the file:</p><pre>user.avatar.attach(params[:avatar])</pre><p>You can also check if a user already has an attachment with this method:</p><pre>user.avatar.attached?</pre><h3>Using Active Storage with existing images</h3><p>Sometimes you have existing images you want to associate with your models. You can do with the attach command again.<br>However, you will specify the io this time as well as the file in question.</p><pre>@message.image.attach(io: File.open(&#39;/path/to/file&#39;), filename: &#39;file.pdf&#39;, content_type: &#39;application/pdf&#39;)</pre><h3>Conclusion</h3><p>ActiveStorage is a useful tool for Rails apps and can definitely power a powerful image use case. The fact that you can simply use or switch over to Amazon or other cloud providers as well is really powerful and can allow your application to scale. What is covered here is the tip of the iceberg and coverage of basic use cases. If you want to learn more, review the Rails docs for Active Storage.</p><h3>Sources</h3><p><a href="https://edgeguides.rubyonrails.org/active_storage_overview.html#has-many-attached">Active Storage Overview - Ruby on Rails Guides</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bb699d77cefe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dockerizing an Existing Rails App]]></title>
            <link>https://jhcheung.medium.com/dockerizing-an-existing-rails-app-2201026b5867?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/2201026b5867</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 28 Sep 2020 03:30:58 GMT</pubDate>
            <atom:updated>2020-09-28T03:35:54.412Z</atom:updated>
            <content:encoded><![CDATA[<p>Dockerizing an existing Rails app will be very similar to my existing guide on <a href="https://medium.com/@jhcheung/using-docker-on-a-new-rails-app-375911df0afd">creating a new Rails app</a>.</p><p>However, there are definitely some differences and nuances.</p><p>First, you have to make sure that you are using postgresql in your app. If that is not the case, you can convert your database using <a href="https://medium.com/@virtual_khan/converting-rails-from-sqlite3-to-postgresql-d97023314a14">this article</a>.</p><p>Then, you will need to define the starter files like with creating a new Rails app in Docker. However, it is a more streamlined process this time, but with many similarities.</p><h3>Dockerfile</h3><p>As discussed in the new Rails app article, you will have to create a new dockerfile that will build the app image. This dockerfile will exist in the root directory of the rails app. Here is the basic template:</p><pre>FROM ruby:2.5<br>RUN apt-get update -qq &amp;&amp; apt-get install -y nodejs postgresql-client<br>RUN mkdir /myapp<br>WORKDIR /myapp<br>COPY Gemfile /myapp/Gemfile<br>COPY Gemfile.lock /myapp/Gemfile.lock<br>RUN bundle install<br>COPY . /myapp<br><br># Add a script to be executed every time the container starts.<br>COPY entrypoint.sh /usr/bin/<br>RUN chmod +x /usr/bin/entrypoint.sh<br>ENTRYPOINT [&quot;entrypoint.sh&quot;]<br>EXPOSE 3000<br><br># Start the main process.<br>CMD [&quot;rails&quot;, &quot;server&quot;, &quot;-b&quot;, &quot;0.0.0.0&quot;]</pre><h3>Entrypoint</h3><p>Next, as with the new rails app, we want to use an entrypoint. This step can be avoided if you are not using the entrypoint in your dockerfile. This file will also exist in the directory of the rails app.</p><pre>#entrypoint.sh<br>#!/bin/bash<br>set -e<br><br># Remove a potentially pre-existing server.pid for Rails.<br>rm -f /myapp/tmp/pids/server.pid<br><br># Then exec the container&#39;s main process (what&#39;s set as CMD in the Dockerfile).<br>exec &quot;$@&quot;</pre><h3>Docker Compose</h3><p>Then, you can build the docker-compose file. You can read more about the docker-compose from my previous article. This last file will also exist in the root directory of the rails app.</p><pre>#docker-compose.yml<br>version: &#39;3&#39;<br>services:<br>  db:<br>    image: postgres<br>    volumes:<br>      - ./tmp/db:/var/lib/postgresql/data<br>    environment:<br>      POSTGRES_PASSWORD: password<br>  web:<br>    build: .<br>    command: bash -c &quot;rm -f tmp/pids/server.pid &amp;&amp; bundle exec rails s -p 3000 -b &#39;0.0.0.0&#39;&quot;<br>    volumes:<br>      - .:/myapp<br>    ports:<br>      - &quot;3000:3000&quot;<br>    depends_on:<br>      - db</pre><h3>Database Settings</h3><p>Then, you can adjust the config/database.yml to point the rails app at the right database:</p><pre>default: &amp;default<br>   adapter: postgresql<br>   encoding: unicode<br><strong><em>   host: db</em></strong><br>   username: postgres<br>   pool: &lt;%= ENV.fetch(&quot;RAILS_MAX_THREADS&quot;) { 5 } %&gt;<br>   timeout: 5000</pre><p>The notable change will be the ‘host: db’ line, allowing the rails app to see the db container.</p><h3>Building the project and setting up the db</h3><p>Lastly, you can build the project and set up the db:</p><pre>$ docker-compose build<br>$ docker-compose run web rake db:create db:migrate<br>$ docker-compose up</pre><p>These steps will build the image off the docker-compose file, then run and generate your database, and lastly run your image in a container.</p><h3><strong>Conclusion</strong></h3><p>At the end of this, you’ll have your Rails app in a docker container that you can access via localhost:3000. However, instead of using <em>rails s</em> in the future to launch your server, you will use ‘<em>docker-compose up</em>’.</p><h3>Sources</h3><ul><li><a href="https://medium.com/@jhcheung/using-docker-on-a-new-rails-app-375911df0afd">Using Docker on a new Rails app</a></li><li><a href="https://docs.docker.com/compose/rails/">Quickstart: Compose and Rails</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2201026b5867" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fixing dependency alerts for node]]></title>
            <link>https://jhcheung.medium.com/fixing-dependency-alerts-for-node-d0a996144150?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/d0a996144150</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 21 Sep 2020 03:49:57 GMT</pubDate>
            <atom:updated>2020-09-21T03:49:57.834Z</atom:updated>
            <content:encoded><![CDATA[<p>As discussed in the <a href="https://medium.com/@jhcheung/fixing-dependency-alerts-for-ruby-a04397be9e23">previous article</a>, github will inform you of dependency alerts for your outdated or insecure dependencies. In the linked article, we discussed updating ruby gems with bundle update to fix this error. Now, we will cover the same steps for npm/node.</p><h3>npm audit</h3><p>The first command to use is</p><pre>npm audit</pre><p>npm audit is actually npm’s provided command and solution to update your dependencies and packages and update them. You would run npm audit to have a list of dependencies, and then run</p><pre>npm audit fix</pre><p>in order to patch the security vulnerabilities.</p><h3>npm install/npm update</h3><p>However, sometimes npm audit doesn’t work. There are multiple reasons why this could happen, but the most common reason is that a parent package of a dependency has not officially updated. The easiest way to fix this is to update the packages manually, with the following commands:</p><pre>npm install &#39;package-name&#39;<br>or<br>npm update &#39;package-name&#39;</pre><p>Updating the package with the security vulnerability manually will allow you to ensure that you are up to date on the package and no longer have the security vulnerability.</p><h3>Conclusion</h3><p>The above steps should generally help you get rid of the dependency alerts for node packages, in a way that is not just dismissing the notification on github, helping you keep up to date and secure.</p><h3>Sources</h3><p><a href="https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities">https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d0a996144150" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fixing dependency alerts for Ruby]]></title>
            <link>https://jhcheung.medium.com/fixing-dependency-alerts-for-ruby-a04397be9e23?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/a04397be9e23</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 14 Sep 2020 03:46:04 GMT</pubDate>
            <atom:updated>2020-09-14T03:46:04.256Z</atom:updated>
            <content:encoded><![CDATA[<p>When using github, from time to time, github will inform you of some security issue from one of the dependencies on one of your repos. It will pop up on the top right of the user interface under the bell icon. After clicking through to your notifications, you will see errors like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dljP3qpCGWW59h20l_nYwg.png" /><figcaption>What do I do?</figcaption></figure><p>Now a lot of the time, the notification is fairly easy to get rid of, as you can just click through to the error and see the pull request that Dependabot has automatically generated. Then, integrating the pull request is as simple as merging it into your master branch and then pulling the change onto your local repo.</p><p>However, sometimes, dependabot can fail and leave an ugly security notification on your user interface:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HHKuJSNDsXGvHxEnmU4agA.png" /></figure><p>The first thing to try would be to retry creating the Dependabot security update. It can sometimes take some time (usually not more than 15 minutes), but if it succeeds, you’re good to go! However, if it fails, you may need to manually update your dependencies in order to get rid of the notification.</p><h3>Updating Dependencies</h3><p>There are two ways of doing this.</p><p>The first way is to just generally run a general bundle update on your local repo:</p><pre>bundle update</pre><p>This works just fine, but you can also use a more targeted approach</p><pre>bundle update actionview</pre><p>You can specify the exact dependency that you want to update — this would be the dependency/gem that is throwing the error on the Github alert.</p><p>After updating the gem, you should have a modified gemfile.lock and sometimes gemfile. In order for the alert to be dismissed from Github, you must then commit these changes:</p><pre>git add .<br>git commit -m &quot;fixed * dependency alert&quot;<br>git push origin master</pre><p>Then, you should have a clear notification queue with resolved security issues! Safe and up to date!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a04397be9e23" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rendering JSX From Strings]]></title>
            <link>https://jhcheung.medium.com/rendering-jsx-from-strings-7cb455a4771d?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/7cb455a4771d</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 07 Sep 2020 03:31:42 GMT</pubDate>
            <atom:updated>2020-09-07T03:31:42.919Z</atom:updated>
            <content:encoded><![CDATA[<p>In building my Slay the Spire app, we created an API that delivered description strings that already had prewritten JSX. This was done so that we could implement keyword tooltips without having to parse the descriptions on the client end.</p><p>However, we ran into a problem — the strings were not being translated into JSX after we piped the prewritten JSX into the React component. Here is an example of that prewritten JSX:</p><pre>&lt;Keyword name=&quot;Exhaust&quot;&gt;&lt;/Keyword&gt; your hand.\nDeal 7 damage for each card &lt;Keyword name=&quot;Exhausted&quot;&gt;&lt;/Keyword&gt;.\n&lt;Keyword name=&quot;Exhaust&quot;&gt;&lt;/Keyword&gt;.&quot;</pre><p>The problem with this is that React would not recognize this as JSX when it was a string piped in from our API. It would show up as simple HTML and would not recognize those keyword names.</p><p>After experimentation with different methods, we decided to use a plugin we found called ‘react-html-parser’:</p><p><a href="https://github.com/wrakky/react-html-parser">wrakky/react-html-parser</a></p><p>Using this plugin, we were able to pass our marked up strings into a prewritten function that allowed us to create JSX.</p><p>Here is how we did it:</p><p>First, we installed this package:</p><pre>npm install react-html-parser --save</pre><p>Then, we imported the library and created a transform function for the code:</p><pre>import ReactHtmlParser from &#39;react-html-parser&#39;;</pre><pre>const options = { transform }</pre><pre>function transform(node, index) {<br>     if (node.type === &#39;tag&#39; &amp;&amp; node.name === &#39;keyword&#39;){<br>         return <br>             &lt;Keyword key={index} name={node.attribs.name} <br>                      keywords={props.keywords}/&gt;;</pre><pre>        }</pre><pre>    }</pre><p>The code simply will transform any node that has a type of “tag” that is named “keyword”. It will recognize the marked up JSX that we created and return a proper JSX component.</p><p>In the render/return output of the component, you can then just input the string of marked up text with the options set up in the above code:</p><pre>ReactHtmlParser(props.card.attributes.keyword_description, options)</pre><p>This way, you can prewrite/markup some JSX code from your API and then use it in your React components with minimal fuss.</p><h3>Sources</h3><p><a href="https://github.com/wrakky/react-html-parser">wrakky/react-html-parser</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7cb455a4771d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Docker on a new Rails app]]></title>
            <link>https://jhcheung.medium.com/using-docker-on-a-new-rails-app-375911df0afd?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/375911df0afd</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 31 Aug 2020 03:36:08 GMT</pubDate>
            <atom:updated>2020-08-31T03:36:08.394Z</atom:updated>
            <content:encoded><![CDATA[<p>As covered in previous articles, Docker is a paradigm shift that allows for developers to share images and develop without as much attention to dependencies.</p><p>Now how do we actually use it for a new application? In this article, I will cover a quick start of Docker use in a rails app.</p><h3>Dockerfile</h3><p>Any Dockerized app begins with the Docker file. Here is a simple template Dockerfile used to bootstrap a Dockerized Rails app.</p><pre>FROM ruby:2.5<br>RUN apt-get update -qq &amp;&amp; apt-get install -y nodejs postgresql-client<br>RUN mkdir /myapp<br>WORKDIR /myapp<br>COPY Gemfile /myapp/Gemfile<br>COPY Gemfile.lock /myapp/Gemfile.lock<br>RUN bundle install<br>COPY . /myapp<br><br># Add a script to be executed every time the container starts.<br>COPY entrypoint.sh /usr/bin/<br>RUN chmod +x /usr/bin/entrypoint.sh<br>ENTRYPOINT [&quot;entrypoint.sh&quot;]<br>EXPOSE 3000<br><br># Start the main process.<br>CMD [&quot;rails&quot;, &quot;server&quot;, &quot;-b&quot;, &quot;0.0.0.0&quot;]</pre><p>You can change the ruby version to your preferred version, and you can also rename the directories as needed. Please just remember to change all the directories to be uniform, in this dockerfile as well as any future files.</p><h3>Creating the starter files</h3><p>As you can see in the dockerfile, we will be using a Gemfile of some sort as well as an entrypoint.sh file. We can now create those.</p><pre>#Gemfile<br>source &#39;https://rubygems.org&#39;<br>gem &#39;rails&#39;, &#39;~&gt;5&#39;</pre><p>This gemfile will quickly be replaced with a Rails gemfile, so don’t worry about it other than this line. Also, please create a Gemfile.lock, which is referenced in the dockerfile as well.</p><pre>touch Gemfile.lock</pre><p>Lastly, create an entrypoint file in the directory which will be run every launch.</p><pre>#entrypoint.sh<br>#!/bin/bash<br>set -e<br><br># Remove a potentially pre-existing server.pid for Rails.<br>rm -f /myapp/tmp/pids/server.pid<br><br># Then exec the container&#39;s main process (what&#39;s set as CMD in the Dockerfile).<br>exec &quot;$@&quot;</pre><p>The last file we will need to create is the docker-compose.yml file.</p><pre>#docker-compose.yml<br>version: &#39;3&#39;<br>services:<br>  db:<br>    image: postgres<br>    volumes:<br>      - ./tmp/db:/var/lib/postgresql/data<br>    environment:<br>      POSTGRES_PASSWORD: password<br>  web:<br>    build: .<br>    command: bash -c &quot;rm -f tmp/pids/server.pid &amp;&amp; bundle exec rails s -p 3000 -b &#39;0.0.0.0&#39;&quot;<br>    volumes:<br>      - .:/myapp<br>    ports:<br>      - &quot;3000:3000&quot;<br>    depends_on:<br>      - db</pre><p>This file will create two separate containers for your database and web app and link them together using docker networking.</p><h3>Project Build</h3><p>With all the files created, you can now use docker commands in order to generate a Rails app skeleton:</p><pre>docker-compose run web rails new . --force --no-deps --database=postgresql</pre><p>This will build the image for <em>web</em> and then run the <em>rails new </em>command, which creates a new rails app.</p><p>This will update your Gemfile through rails new, so now you can rebuild the image using docker-compose.</p><pre>docker-compose build</pre><h3>Setting up the Database</h3><p>Last thing to do will be to point the Rails configuration to the db container that you created for Docker. You can do this by changing the <em>host </em>property in the Docker <em>config/</em>database.yml file.</p><pre>config/database.yml<br>default: &amp;default<br>  adapter: postgresql<br>  encoding: unicode<br>  host: db<br>  username: postgres<br>  password: password<br>  pool: 5<br><br>development:<br>  &lt;&lt;: *default<br>  database: myapp_development<br><br><br>test:<br>  &lt;&lt;: *default<br>  database: myapp_test</pre><p>After this, you will be able to launch the app using docker-compose properly:</p><pre>docker-compose up</pre><p>Lastly, you can create the database, using this command in another terminal:</p><pre>docker-compose run web rake db:create</pre><p>This will now allow you to access the Rails app via your localhost:3000, as detailed in the docker-compose.yml configuration. You can also change the port you want to access by modifying that file.</p><h3>Recap Basic Commands</h3><pre>docker-compose up</pre><p>This will launch the docker-compose app in the directory you are in. In this case, it will launch both the database and web applications that you have set up in this guide. You can also add the -d flag to run the application detached, but that will require the next command to exit.</p><pre>docker-compose down</pre><p>This is essentially the opposite of the docker-compose up command and will go through the process to quit your app.</p><pre>docker-compose build</pre><p>This will rebuild the docker-compose image. This will be needed if you make changes to the gemfile or the compose file to try different configurations. You can also full rebuild using the following command:</p><pre>docker-compose run web bundle install</pre><p><em>Docker-compose run web </em>in general will allow you to run many of the commands you were used to in Rails development. For example, to use ‘rails db:migrate’, you would use this:</p><pre>docker-compose run web rake db:migrate</pre><h3>Sources</h3><p>This article is primarily sourced through the following instructions:</p><p><a href="https://docs.docker.com/compose/rails/">Quickstart: Compose and Rails</a></p><p>I have provided more context and color to the explanations, as well as a recap of the basic commands you will use to interact with the dockerized app.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=375911df0afd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Serving Arrays via Rails API]]></title>
            <link>https://jhcheung.medium.com/serving-arrays-via-rails-api-c676bb89f9e6?source=rss-df62cd40ab78------2</link>
            <guid isPermaLink="false">https://medium.com/p/c676bb89f9e6</guid>
            <dc:creator><![CDATA[Jimmy Cheung]]></dc:creator>
            <pubDate>Mon, 24 Aug 2020 03:32:34 GMT</pubDate>
            <atom:updated>2020-08-24T03:32:34.453Z</atom:updated>
            <content:encoded><![CDATA[<p>When building out my <a href="https://github.com/jhcheung/slay-the-spire-api">Slay the Spire Rails API</a> app, I ran into an issue in developing my frontend. When I accessed my <em>api/v1/keywords</em> endpoint and looked at my “<em>names</em>” array, I was only able to access a string, and was not able to access an array, like I had intended.</p><p>Why was this happening? I had built out my database with help from a JSON file that had utilized arrays, so it should be showing the same thing from Rails, right?</p><p>Wrong! I had overlooked a critical part of this process. When I set up my database, I set my keywords table to be a string. Because of that, my Rails API was just serving a string!</p><pre>create_table “keywords”, force: :cascade do |t|</pre><pre>   t.string “name”</pre><pre>   t.string “description”</pre><pre>   t.string “names”</pre><pre>   t.datetime “created_at”, precision: 6, null: false</pre><pre>   t.datetime “updated_at”, precision: 6, null: false</pre><pre>end</pre><p>Above is my schema.rb, which shows that “names” was a string.</p><h3>How to fix this</h3><p>Now, I had to figure out how to fix this issue. First, I thought it would be a expensive mistake, and I would have to redo my migrations and database to have my schema show an array of some sort. This would require me to drop my database, reload it, and start over. It could also potentially cause issues that could reset my progress from other parts of my code.</p><pre>class CreateSomething &lt; ActiveRecord::Migration<br>  def change<br>    create_table :something do |t|<br>      t.string :some_array, array: true, default: []<br>      t.timestamps<br>    end<br>  end<br>end</pre><p>Above would be a migration file that I imagined I would need in order to reclassify my array.</p><p>However, I figured out a quick way to do this inside the Rails toolset!</p><p>In my Rails model, I simply added one line of code that solved this dilemma.</p><pre>class Keyword &lt; ApplicationRecord</pre><pre>    serialize :names, Array</pre><pre>end</pre><p>With that line, I was then able to serve the names property as an array, fixing that bug from my backend!</p><h3>Sources</h3><ul><li><a href="https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html">https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c676bb89f9e6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>