<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Rails - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Rails - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 22:21:09 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/rails/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Install Rails on Ubuntu and Update Ruby to the Latest Version ]]>
                </title>
                <description>
                    <![CDATA[ By Adebola Adeniran A couple of months ago, when I learned Ruby-on-Rails for the first time, I had to work on a collaborative project with a coding partner. We kept running into issues, as he had a different version of Rails and Buby setup for the pr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-rails-on-ubuntu-and-update-ruby-to-the-latest-version/</link>
                <guid isPermaLink="false">66d45d5d51f567b42d9f840f</guid>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 01 Jul 2020 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/Slice-3-1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adebola Adeniran</p>
<p>A couple of months ago, when I learned Ruby-on-Rails for the first time, I had to work on a collaborative project with a coding partner. We kept running into issues, as he had a different version of Rails and Buby setup for the project. I couldn't wrap my head around how to install the versions the project needed. </p>
<p>Here's the guide I wish I had. It also shows you how to switch the version of Ruby or Rails you're using, depending on the projects you're working on.</p>
<p>First, let's get the latest version of Ruby installed. To do this, we need to install a package called <strong>RVM - Ruby version manager.</strong> This package lets us install ANY version of Ruby on our Ubuntu machine and allows us to switch between versions.</p>
<p>All the code here will be run using the Ubuntu CLI/terminal.</p>
<h2 id="heading-installing-rvm">Installing RVM</h2>
<ol>
<li>First, we need to install a pre-requisite. Open up your Ubuntu terminal and type the command:</li>
</ol>
<pre><code>sudo apt-get install software-properties-common
</code></pre><p>Next, we need to add the <strong>PPA (Personal Package archive)</strong>. A PPA is how we get files distributed by developers that are yet to make it to the official Ubuntu package/app store. </p>
<p>It's also a way for developers to distribute the latest versions of their software while waiting for Ubuntu to test and publish that software in the official store.</p>
<pre><code>sudo apt-add-repository -y ppa:rael-gc/rvm
</code></pre><p>The command above adds the PPA to the list of locations we can download packages from on our Ubuntu machine.</p>
<p>Next, let's refresh our list of packages by running:</p>
<p><code>sudo apt-get update</code></p>
<p>Finally, let's install RVM itself.</p>
<pre><code>sudo apt-get install rvm
</code></pre><p>Now restart your terminal for your changes to take effect. Then, type <code>rvm version</code> and hit <code>enter</code> to check that rvm is installed. You should get a response like this:</p>
<p><code>rvm 1.29.10 (manual) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [[https://rvm.io](https://rvm.io)]</code></p>
<h2 id="heading-installing-ruby">Installing Ruby</h2>
<p>Now we can install the latest Ruby version which is 2.7.1. Run the command <code>rvm install 2.7.1</code>. Alternatively, you can run <code>rvm install ruby</code> which will install the latest stable version (this will install v2.7.0).  </p>
<p>To see what Ruby versions you have installed, run <code>rvm ls</code>. To switch between Ruby versions, run <code>rvm use &lt;version_number&gt;</code> (for example, <code>rvm use 2.7.1</code>).</p>
<h2 id="heading-installing-ruby-on-rails">Installing Ruby-on-Rails</h2>
<p>The latest version of Rails is at 6.03. Rails is simply a Ruby gem, and with Ruby installed we can install Rails! Run <code>gem install rails</code> to install the latest version of Rails.  </p>
<p>Finally, to check that all went well, run <code>rails -v</code>. You should get <code>Rails 6.0.3.2</code> back, as this is the latest version at the time of publishing this article.   </p>
<p>You can now start your first Rails project by typing <code>rails new myapp</code>.</p>
<p>Hey, you're now on Rails!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add JavaScript to Your Rails 6 App ]]>
                </title>
                <description>
                    <![CDATA[ By Daniel Wesego As a junior Full-Stack developer, my main focus was the backend. I wanted to learn how to program my backend server to serve my web application.  But after learning the basics of the the backend, I learned that the frontend was just ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-javascript-to-your-rails-6-app/</link>
                <guid isPermaLink="false">66d45e007df3a1f32ee7f7f1</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 10 Apr 2020 16:04:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/carl-heyerdahl-KE0nC8-58MQ-unsplash--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Daniel Wesego</p>
<p>As a junior Full-Stack developer, my main focus was the backend. I wanted to learn how to program my backend server to serve my web application. </p>
<p>But after learning the basics of the the backend, I learned that the frontend was just as important as the backend. And one way to increase the liveliness of your web application is by adding JavaScript.</p>
<p>JavaScript is essential to add interactivity to your web application. Of course, it has become far more than that now. It is a programming language that web browsers run. Many websites you have visited use some JavaScript code in their frontend. </p>
<p>You may have started using Ruby on Rails to build your web application and wondered how to add JavaScript to your code. In this article, I'll show you how to add JavaScript code to your Rails app.</p>
<h2 id="heading-why-javascript">Why JavaScript?</h2>
<p>You may wonder why you even need JavaScript in your web application in the first place. In short, if you don't include any JS, then your web application's user experience will not be good.</p>
<p>Let's say you have a form that a user fills out and you want to do form validation. If the user submits the form without filling in the proper values, the page for the form has to reload again, hitting the server and coming up again for the user. That takes a lot of time and will probably annoy the user.</p>
<p>Of course you can sometimes get away with HTML form validation, but that's not always possible. Adding a simple script that checks the user inputs and notifies them that they should input the correct information is much better.</p>
<p>Of course this doesn't mean you can ignore server side validation, but that's for another article.</p>
<p>Another use case is loading files asynchronously, which you can do in JavaScript without reloading the whole page. You may have used some web apps that load more pictures and articles as you scroll down without having to refresh or change the page over and over again.</p>
<p>These and other use cases are great reasons to use JavaScript in your application. In fact, the demand for JavaScript has been increasing. You can even use it to write your backend. </p>
<p>But we love Rails, so we are going to stick with it for a while. </p>
<h2 id="heading-what-well-cover-here">What we'll cover here</h2>
<p>At the time of writing, the latest version of the framework is Rails 6, and it has brought some changes to the way you interact with JavaScript. </p>
<p>Prior to Rails 6, we had the asset pipeline to manage CSS and JavaScript files. But starting from Rails 6, Webpacker is the default compiler for JavaScript. CSS is still managed by the asset pipeline, but you can also use Webpack to compile CSS. </p>
<p>You won't find your JavaScript folder in the same place as you did in Rails 5. The directory structure for JavaScript has changed to the <strong>app/javascript/packs/</strong> folder.</p>
<p>In that folder you will find the <strong>application.js</strong> file, which is just like the <strong>application.css</strong> file. It will be imported by default in the <strong>application.html.erb</strong> file when you create your new Rails app. </p>
<p>The <strong>application.html.erb</strong> file will be used by all views. </p>
<h2 id="heading-adding-a-script-that-will-be-used-by-all-views">Adding a script that will be used by all views</h2>
<p>If you want your JavaScript to be available in all views or pages, you can just put it in the <strong>application.js</strong> file:</p>
<pre><code class="lang-js"><span class="hljs-built_in">require</span>(<span class="hljs-string">"@rails/ujs"</span>).start()
<span class="hljs-built_in">require</span>(<span class="hljs-string">"turbolinks"</span>).start()
<span class="hljs-built_in">require</span>(<span class="hljs-string">"@rails/activestorage"</span>).start()
<span class="hljs-built_in">require</span>(<span class="hljs-string">"channels"</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Hello from application.js'</span>)
</code></pre>
<p>The first four lines are there by default. I have added a <code>console.log</code> statement to show you that the JavaScript will be available everywhere. </p>
<p>You can test this by viewing any page in your application and opening the developer console. </p>
<p>But you may not always want your JavaScript code to be loaded on every page. Instead, you can make the script available only when visiting a specific page.</p>
<h2 id="heading-adding-a-script-that-will-be-used-by-a-specific-file">Adding a script that will be used by a specific file</h2>
<p>If you want your JavaScript to be available for only a specific view, then you can use the <strong>javascript_pack_tag</strong> to import that specific file:</p>
<pre><code class="lang-html.erb">&lt;h1 class='text-center'&gt;I want my JS here only&lt;/h1&gt;

&lt;%= javascript_pack_tag 'my_js' %&gt;
</code></pre>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Hello from My JS'</span>)
</code></pre>
<p>Remember that you need to add the file in the <strong>packs</strong> directory. The <strong>javascript_pack_tag</strong> should also refer to the name of the JavaScript file you created. </p>
<p>Now the script will only run when the specific view that includes the <strong>javascript_pack_tag</strong> is loaded in the browser.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>I hope this article helps clear up any confusion you might have when updating your app to Rails 6, or if you just got started with Rails. </p>
<p>You can follow me on <a target="_blank" href="https://github.com/DanielMitiku">Github</a> if you want to learn more.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to create a Rails project with a React and Redux front-end ]]>
                </title>
                <description>
                    <![CDATA[ By Mark Hopson A complete guide to setting up a single-page Javascript App with React and Redux inside a Rails project. Update (Mar 17, 2019): Added Typescript to the last step of this project. This tutorial will show you how to create a single-page... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-rails-project-with-a-react-and-redux-front-end-8b01e17a1db/</link>
                <guid isPermaLink="false">66c35103a7aea9fc97bdfb8f</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Redux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 15 Mar 2019 16:42:24 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*EtGyA7lw9v-oJqZjJs2AZQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Mark Hopson</p>
<h4 id="heading-a-complete-guide-to-setting-up-a-single-page-javascript-app-with-react-and-redux-inside-a-rails-project">A complete guide to setting up a single-page Javascript App with React and Redux inside a Rails project.</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1DRlu00V4rUeQFcC64Muori13cH2tdM94tEw" alt="Image" width="800" height="283" loading="lazy"></p>
<p><em>Update (Mar 17, 2019): Added <a target="_blank" href="https://github.com/Microsoft/TypeScript">Typescript</a> to the last step of this project.</em></p>
<p>This tutorial will show you how to create a <a target="_blank" href="https://www.bloomreach.com/en/blog/2018/07/what-is-a-single-page-application.html">single-page app</a> with React (and <a target="_blank" href="https://redux.js.org/">Redux</a> and <a target="_blank" href="https://react.semantic-ui.com/">Semantic UI</a>) inside a Rails project.</p>
<p>This tutorial will also include:</p>
<ul>
<li><a target="_blank" href="https://redux.js.org/">Redux</a></li>
<li><a target="_blank" href="https://github.com/ReactTraining/react-router">React Router</a></li>
<li><a target="_blank" href="https://github.com/reduxjs/reselect">Reselect</a></li>
<li><a target="_blank" href="https://github.com/reduxjs/redux-thunk">Redux Think</a></li>
<li><a target="_blank" href="https://react.semantic-ui.com/">Semantic UI</a></li>
</ul>
<p><em>Side note #1. I saw this <a target="_blank" href="https://medium.freecodecamp.org/how-to-make-create-react-app-work-with-a-node-backend-api-7c5c48acb1b0">wonderful guide</a> recently and it inspired me to write one for Rails.</em></p>
<p><em>Side note #2. Here is the <a target="_blank" href="https://github.com/markhopson/rails-react-tutorial">finished tutorial</a>. The <a target="_blank" href="https://github.com/markhopson/rails-react-tutorial/commits/master">commit history</a> corresponds (kind of) with the steps in this guide.</em></p>
<h3 id="heading-overview">Overview</h3>
<p>To give you a sense of what we’re going to build and how things will work, see the 2 diagrams below.</p>
<h4 id="heading-diagram-1-handling-the-first-http-request-ie-requests-from-the-browser-to-our-rails-app">Diagram 1: Handling the first HTTP request (i.e. requests from the browser to our Rails App)</h4>
<p>The diagram below illustrates your React App inside your Rails project, and the path (solid black line) that the first request takes to return the <strong>React App</strong> back to the client (browser).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/OxcrUVaQKCApwVhTqP2MpevTsr9O6uBVBK6u" alt="Image" width="800" height="281" loading="lazy">
<em>Diagram 1: How our project handles the first request from the client (i.e. browser)</em></p>
<h4 id="heading-diagram-2-handling-subsequent-http-requests-ie-requests-from-our-react-app-to-our-rails-app">Diagram 2: Handling subsequent HTTP requests (i.e. requests from our React App to our Rails App)</h4>
<p>After the React App is loaded in the user’s browser, the React App will be responsible for sending requests to your Rails App (solid black line). In other words, once React is loaded, requests to Rails will come from Javascript code, and not the browser.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PEaEcl3jJ6J0QUzGCQREKB9ovNgWn1kAUuNB" alt="Image" width="800" height="283" loading="lazy">
<em>Diagram 2: How React interacts with Rails (HTTP requests will come from in the React App and not the browser itself)</em></p>
<h4 id="heading-other-important-notes-before-we-start-coding">Other Important notes before we start coding</h4>
<ul>
<li>Think of your React App as being separate from your Rails App. The React App is strictly for the front-end and runs in the user’s browser. The Rails part is strictly for the back-end and runs on the server. The Rails App does not know anything about the React App except for when to return its static assets (Webpack compiled HTML, JS, and CSS).</li>
<li>Once your React App is loaded by your browser, all the logic to make HTTP requests (retrieve data, and turn that data into a view) is done in the front-end (i.e. browser).</li>
<li>Your Rails App effectively does not serve any views except for the one that serves your React App. In this tutorial, the only Rails view is <code>/app/views/static/index.html.erb</code></li>
<li>All <code>/api/*</code> paths gets handled by the Rails App, while all other paths gets handled by React inside the browser (after your browser has loaded the first request). For example, <code>[http://your-app.com/something](http://your-app.com/something)</code> will be sent to the Rails App, and then returned back to your React App (the HTML/JS/CSS that has already loaded in the browser), which will decide what to show on the screen.</li>
<li><a target="_blank" href="https://medium.freecodecamp.org/why-i-hate-your-single-page-app-f08bb4ff9134">Considerations for building a single-page app</a>. Not necessary for this tutorial but useful.</li>
<li><a target="_blank" href="https://medium.com/teamsubchannel/react-component-patterns-e7fb75be7bb0">React Component design patterns</a>. Again, not necessary but useful.</li>
</ul>
<h3 id="heading-system-requirements">System Requirements</h3>
<p>FYI here’s my system config. Not saying you need this, but something similar will make this tutorial experience smoother.</p>
<ul>
<li>macOS 10.13.6 (High Sierra)</li>
<li>Ruby 2.5.1</li>
<li>Rails 5.2.1 (and Bundler 1.16.6)</li>
<li><ul>
<li>gem install bundler -v 1.16.6</li>
</ul>
</li>
<li>Node 9.8.0</li>
</ul>
<p>Finally, on to the code!</p>
<h3 id="heading-step-1-create-a-new-rails-project-with-webpack-and-react">Step 1: Create a new Rails project with Webpack and React</h3>
<p>Create a new Rails app. I’ve named mine <code>rails-react-tutorial</code>.</p>
<pre><code>rails <span class="hljs-keyword">new</span> rails-react-tutorial --webpack=react
</code></pre><p>See <a target="_blank" href="https://guides.rubyonrails.org/5_1_release_notes.html#optional-webpack-support">here</a> for more info on the <code>--webpack=react</code> flag introduced in Rails 5.1.</p>
<h3 id="heading-step-2-make-sure-the-webpacker-and-react-rails-gems-are-installed">Step 2: Make sure the Webpacker and React-Rails gems are installed</h3>
<p>Check if the <a target="_blank" href="https://github.com/rails/webpacker"><strong>Webpacker</strong></a> and <a target="_blank" href="https://github.com/reactjs/react-rails"><strong>React-Rails</strong></a> gems are in your <code>Gemfile</code>. If the gems are not there, then add it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/dJaidHtjRCjdyj6rbyLpzO614UFTN2H8RJ1J" alt="Image" width="800" height="347" loading="lazy">
<em>Sometimes only Webpacker is added, and not React-Rails; not sure why …</em></p>
<p>Now run these commands to install everything.</p>
<pre><code>bundle install
</code></pre><pre><code># This command might not be necessary.# If already installed, then it will# ask you to override some files.rails webpacker:install
</code></pre><pre><code>rails webpacker:install:react  rails generate react:installyarn install
</code></pre><p>Now run <code>rails server -p 3000</code> and visit <code>[http://localhost:3000](http://localhost:3000)</code> to make sure our project is working.</p>
<p><strong>Pro Tip #1</strong>: run <code>./bin/webpack-dev-server</code> in a separate window while coding to have any changes automatically build and reload the browser.</p>
<p><strong>Pro Tip #2</strong>: If you get this error <code>can’t activate sqlite3 (~&gt; 1.3.6), already activated sqlite3–1.</code>4.0 then a<code>dd gem ‘sqlite3’, ‘~&gt;</code> 1.3.6’ to Gemfile. See <a target="_blank" href="https://stackoverflow.com/a/54529016/1176788">thi</a>s link for more info.</p>
<h3 id="heading-step-3-add-a-controller-class-and-route-to-our-rails-app">Step 3: Add a Controller class, and Route, to our Rails app</h3>
<p>Add a new route to our Rails app. For this example, we will add <code>GET /v1/things</code> endpoint to `config/routes.rb``.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/m5F9mTi3f5w0PYylit7AGcwehshPSZDPcM9L" alt="Image" width="800" height="253" loading="lazy">
<em>Our <code>config/routes.rb</code> file</em></p>
<p>This new route will require a ThingsController. Create a new <code>app/controllers/v1/things_controller.rb</code> file. Remember, it should be in the <code>v1</code> folder because it belongs to our Rails API.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9PLtIbLYPQ1KNyl8nVQqVenLl-ZixF5pGwJa" alt="Image" width="800" height="353" loading="lazy">
_Our /app/controllers/v1/things<em>controller.rb file</em></p>
<p>Our Things controller will return a hard-coded response for <code>GET /v1/things</code>.</p>
<p>At this point, you should be able to re-run <code>rails server -p 3000</code> and visit <code>[http://localhost:3000/v1/things](http://localhost:3000/v1/things)</code>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/dW22FrdU6la7-AbXdjnFSzcsHwoDnt2ULL5B" alt="Image" width="800" height="218" loading="lazy">
<em>Success!</em></p>
<p>Next, we will create a new React component.</p>
<h3 id="heading-step-4-generate-a-new-react-component">Step 4: Generate a new React component</h3>
<p>Create a HelloWorld React component that accepts a String parameter named <code>greeting</code> by running the following command:</p>
<pre><code>rails generate react:component HelloWorld greeting:string
</code></pre><p>A file should be created: <code>app/javascript/components/HelloWorld.js</code>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/zFqPQS1aINW85gTBqLfG01mTiEAflXq798ih" alt="Image" width="800" height="424" loading="lazy">
<em>Our <code>app/javascript/components/HelloWorld.js file</code></em></p>
<h3 id="heading-step-5-use-our-helloworld-component">Step 5: Use our HelloWorld component</h3>
<p>To use and see our new HelloWorld component we need to 2 things: create a view embeds this component, and add a route to point to this view.</p>
<p>To create a view, create the file <code>app/views/static/index.html.erb</code> and add the following:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/BFbI3X9mTUdmccYrrl3jqvbJOw8PNmmxSIag" alt="Image" width="800" height="151" loading="lazy">
<em>“Hello” is being passed in as the “greeting” param for HelloWorld</em></p>
<p>For our new route, add the following line to our <code>routes.rb</code> file, and an empty StaticController to support it.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/KqdYPbAdYPyXpQRjF0ELU17XwZiY7dCaMuP1" alt="Image" width="800" height="241" loading="lazy">
<em>Adding a route to serve our new view that contains the HelloWorld component</em></p>
<p>Add this to <code>app/controllers/static_controller.rb</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/NABHDjdE4RwGEibcfxXFR10IpTbqlqEs9Sr4" alt="Image" width="800" height="168" loading="lazy">
<em>An empty controller</em></p>
<p>You should now be able to re-run <code>rails server -p 3000</code> and visit <code>[http://localhost:3000/](http://localhost:3000/v1/things)</code> to see your new React component (remember to run <code>./bin/webpack-dev-server</code> in a separate window to have an Javascript changes automatically get packaged by webpack).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/LJbFwbm0ntl7zQzL937w4CgsrcjencsnMAYm" alt="Image" width="800" height="170" loading="lazy">
<em>Success! Our first rendered component.</em></p>
<p>Now that we have a React component that renders in our view, let’s expand our app to support multiple views with <code>react-router</code>.</p>
<h3 id="heading-step-6-add-react-router">Step 6: Add React-Router</h3>
<p>First, run this command to add <code>react-router-dom</code>, which includes and exports all of <code>react-router</code> and some additional helper components for web browsing. More info <a target="_blank" href="https://github.com/ReactTraining/react-router/issues/4648">here</a>.</p>
<pre><code>npm install --save react-router-domyarn install
</code></pre><p>This command should add the following line to your <code>package.json</code> file. Note, 4.2.2 was used here, but your version could be different.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/WJnBf1C9vRH45WCQ9Hce8Eu9UdXxwNUjNYC4" alt="Image" width="800" height="394" loading="lazy"></p>
<p>Now let’s use React Router to make some routes for our React Front-End.</p>
<h3 id="heading-step-6-using-react-router">Step 6: Using React-Router</h3>
<p><code>[react-router](https://github.com/ReactTraining/react-router)</code> allows us to manage all our UI routes strictly with Javascript. This means that we will need a single “App” component that encapsulates our entire application. “App” will also use React-Router to present the correct “Page” component for the URL being requested.</p>
<p>To start, run this command to add an App component that will represent our entire front-end application.</p>
<pre><code>rails generate react:component App
</code></pre><p>Next, open the file for the newly created React component, <code>app/javascript/components/App.js</code>, and add the following …</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/6K0h9rD17Rj7vsY8K8JlUMoW57aKRohhYZvx" alt="Image" width="800" height="527" loading="lazy">
<em>Our React App with 2 routes</em></p>
<p>Now change <code>index.html.erb</code> to point to our new App component.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/uzdNclc4C2wOXwQjUrN-3BjdUgiXgtsYuNI3" alt="Image" width="800" height="170" loading="lazy">
<em>The App component will encapsulate our entire front-end.</em></p>
<p>Lastly, edit your <code>routes.rb</code> to have Rails send all requests that are not for the API to our App component (via <code>StaticController#index</code>).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5VVRBI2cAQA8IRGGyesRBsbI2N3tr3TUQ8gy" alt="Image" width="800" height="305" loading="lazy">
<em>Our routes.rb now forwards all non-API and non-Ajax requests to our React App</em></p>
<p>We can now run <code>rails server -p 3000</code> and visit <code>[http://localhost/](http://localhost/)</code> and <code>[http://localhost/](http://localhost/)hello</code> to see React-Router working (remember <code>./bin/webpack-dev-server</code> enables auto-webpacking).</p>
<p>Next, we’ll need to install some additional dependencies before we can connect our React front-end to our Rails API.</p>
<h3 id="heading-step-7-adding-redux-sagas-babel-polyfill-and-axios">Step 7: Adding Redux, Sagas, Babel Polyfill, and Axios</h3>
<p>Now let’s add the following Javascript libraries for our front-end.</p>
<ul>
<li><a target="_blank" href="https://redux.js.org/">Redux</a> to manage the global state of our application.</li>
<li>Babel-Polyfill to enable fancy Javascript features that might not otherwise be available on older web browsers.</li>
<li><a target="_blank" href="https://github.com/reduxjs/reselect">Reselect</a> and <a target="_blank" href="https://github.com/reduxjs/react-redux">React-Redux</a> to make working with Redux easier.</li>
</ul>
<p>To install everything, run the following:</p>
<pre><code>npm install --save redux babel-polyfill reselect react-reduxyarn install
</code></pre><p>Now we will use these tools to set up a Redux State Store, then add some Actions and Reducers to use it.</p>
<h3 id="heading-step-8-set-up-redux-state-store">Step 8: Set up Redux State Store</h3>
<p>In this step, we will set up the Redux State Store for our app with the following template (we will add and remove “things” in the next steps).</p>
<pre><code>{  <span class="hljs-string">"things"</span>: [    {      <span class="hljs-string">"name"</span>: <span class="hljs-string">"..."</span>,      <span class="hljs-string">"guid"</span>: <span class="hljs-string">"..."</span>    }  ]}
</code></pre><p>First, create a <code>configureStore.js</code> file. This will initialize our Redux Store.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ZFFfX1kN-fXNEcHoy2utcuIwXWyVjVHOjP49" alt="Image" width="800" height="614" loading="lazy">
<em>Code to initialize our Redux State, and our first Reducer!</em></p>
<p>Now import and use <code>configureStore()</code> in the App Component to create a Redux State and hook it up to our App.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/JJlz1mKfcn0xk-tvyBX6ROtdd20jJWNHg3Y9" alt="Image" width="800" height="692" loading="lazy">
<em>Initializing the Redux State for our App</em></p>
<p>Now you have Redux installed in your app! Next, we will create an Action and a Reducer, and begin to write and read from our Redux State.</p>
<h3 id="heading-step-9-add-an-action-and-a-reducer">Step 9: Add an Action and a Reducer</h3>
<p>Now that the App has a Redux State, we will add a <code>&lt;butt</code>on&gt; to HelloWorld that dispatches an Action (that we will define here) that will be received b<code>y the rootRed</code>ucer().</p>
<p>First, add <code>getThings()</code> Action definition and import <code>createStructuredSelector()</code> and <code>connect()</code> into theHelloWorld Component. This maps parts of the Redux State, and Actions (i.e. dispatching <code>getThings()</code>) , to HelloWorld’s prop.</p>
<p>Next, add a <code>&lt;butt</code>on&gt; to HelloWorld that dispatc<code>hes a getTh</code>ings() Action (from ./actions/index.js) on every click.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/OC1z0BMnwot2dpGpdw8nLeE7KV299yL8FuAD" alt="Image" width="800" height="700" loading="lazy">
<em>HelloWorld component with all some new Redux helper code</em></p>
<p>After everything is added to HelloWorld, go to <code>[http://localhost:3000/hello](http://localhost:3000/hello)</code>, open the Console, and click the “getThings” button to see your Action and Reducer functions being called.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/JBA5AG2Mn7v0I3feseWjvqiuNveoOMndQhxk" alt="Image" width="800" height="499" loading="lazy">
<em>Look at the console.log() output to see our Action being dispatched</em></p>
<p>Now that you can send an Action that can be received by a Reducer, let’s have the Reducer alter the Redux State.</p>
<h3 id="heading-step-10-have-helloworld-read-react-state-and-display-things">Step 10: Have HelloWorld read React State and display “things”</h3>
<p>Insert a List <code>&lt;</code>ul&gt; in HelloWorld and fill it with “things” from your Redux State.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/U3gFj45R0kzszZFr316Bw70OfkjKtelrBGpB" alt="Image" width="800" height="725" loading="lazy">
<em>HelloWorld with &lt;ul&gt; that reads “things” from our Redux State</em></p>
<p>To test if this is actually working, we can initialize with some “things” data. Once this is done, we can refresh the page and see it in our list.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/LpMQNM4kxe10tI8otmMB2qvj6YmoRjYiLdFf" alt="Image" width="800" height="605" loading="lazy">
<em>Initialize our Redux State with some “things” to see if the front-end &lt;ul&gt; is reading it properly</em></p>
<p>Now that we have a simple Action and Reducer working, we will extend this so that the Action queries our Rails API and the Reducer sets the content of “things” with the API response.</p>
<h3 id="heading-step-11-install-redux-thunk">Step 11: Install Redux-Thunk</h3>
<p>We will need <a target="_blank" href="https://github.com/reduxjs/redux-thunk">Redux-Thunk</a> to allow async workflows (like an HTTP request) to dispatch Actions.</p>
<p>Install <code>redux-thunk</code> by running this command:</p>
<pre><code>npm install --save redux-thunkyarn install
</code></pre><p>Now, let’s use Thunk in our Action!</p>
<h3 id="heading-step-12-use-redux-thunk-and-fetch-to-query-api-and-set-react-state-with-results">Step 12: Use redux-thunk and fetch() to query API and set React State with results</h3>
<p>First, let’s import <code>redux-thunk</code> in <code>configureStore.js</code> and install it our Redux Store so our App can handle “Thunk” Actions.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/iT1D-L38aPRqNJ2QsSDHancSC127DJhDXP0J" alt="Image" width="800" height="541" loading="lazy">
<em>Need to install Redux Thunk as a Redux middleware in our App.</em></p>
<p>Now test that everything is working by starting the App and loading a page.</p>
<p>Next, let’s change the <code>getThings()</code> Action to return a function that performs the following (instead of returning the Action object):</p>
<ol>
<li>Dispatch the original Action object</li>
<li>Make a call to our Rails API.</li>
<li>Dispatch a new Action <code>getThingsSuccess(json)</code> when the call succeeds.</li>
</ol>
<p>For this step, we will also need to add the <code>getThingsSuccess(json)</code> Action.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3AwByGTFi23tAaCgqnWW3QwRgYIqphlUY7-v" alt="Image" width="800" height="892" loading="lazy">
<em>Our new getThings() Action function that does a lot more than returning a simple object — thanks to Redux Thunk!</em></p>
<p>Of course, this does nothing to the Redux State since our Reducer is not making any changes. To fix this, change the Reducer to handle the <code>GET_THINGS_SUCCESS</code> Action and return the new State (with the response from the Rails API).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/-UxcmjkYR2YlPIweMTsxfdwVAaUyU69crZ-Y" alt="Image" width="800" height="735" loading="lazy">
_Have our Reducer change the Redux State when GET_THINGS<em>SUCCESS is dispatched</em></p>
<p>Now if you start your App, navigate to <code>localhost:3000/hello</code> and click the button, your list should change!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/NZxGKdIcW1rM6E5pJzenNmAjHCPBVsWNPwah" alt="Image" width="800" height="263" loading="lazy"></p>
<p>There you have it. A Rails API hooked up to a React+Redux App.</p>
<h3 id="heading-bonus-step-13-installing-redux-dev-tools">(Bonus) Step 13: Installing Redux Dev Tools</h3>
<p>Maybe I should’ve put this step earlier, but <a target="_blank" href="https://github.com/zalmoxisus/redux-devtools-extension">Redux Dev Tools</a> is essential for debugging the Actions your App is sending, and how those Actions are changing your State.</p>
<p>This is how you install it. First, install the proper extension for your browser (<a target="_blank" href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd">Chrome</a>, Firefox).</p>
<p>Next, run the following to install the library.</p>
<pre><code>npm install --save-dev redux-devtools-extensionyarn install
</code></pre><p>Now, use it to initialize your Redux State Store.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/zTmpSPNOpouTQyaatbSIHPrzZ8R8CLpv9hQQ" alt="Image" width="800" height="655" loading="lazy">
<em>Install Redux Dev Tools in your App. You will need to do some extra modifications to turn this off in production mode.</em></p>
<p>After all this is done, you should be able to see a new tab, Redux, in your Chrome (or Firefox) dev tools, that lets you see which Actions were dispatched, and how each one changed the App’s State. The React tab will also show you all your components and their props and states.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/n15RQgRcGRJEITAOoot0g6kzYbkSjcpqDhgG" alt="Image" width="800" height="446" loading="lazy">
<em>Debugging React Components and Redux State/Actions gets 100x easier with this</em></p>
<p>Happy debugging!</p>
<h3 id="heading-bonus-step-14-semantic-ui">(Bonus) Step 14: Semantic UI</h3>
<p>Semantic is a great library for UI components that makes it really easy to build nice looking websites quickly.</p>
<p>To install this library, run the following.</p>
<pre><code>npm install --save semantic-ui-css semantic-ui-reactyarn install
</code></pre><p>Add this to <code>app/javascript/packs/application.js</code>:</p>
<pre><code><span class="hljs-keyword">import</span> <span class="hljs-string">'semantic-ui-css/semantic.min.css'</span>;
</code></pre><p>And add this to <code>app/views/static/index.html.erb</code>:</p>
<pre><code>&lt;%= stylesheet_pack_tag <span class="hljs-string">"application"</span>, :<span class="hljs-function"><span class="hljs-params">media</span> =&gt;</span> <span class="hljs-string">'all'</span> %
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/Fpgw4oXiZW8Y6p9AvBh1LnOnsZRZhijF6FsB" alt="Image" width="800" height="533" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/R8-0PWhJrXjIjXXeCUoiIVfFYTck1REyHrtB" alt="Image" width="702" height="314" loading="lazy">
<em>Nice UI made easy!</em></p>
<h3 id="heading-bonus-step-15-using-a-reasonable-directory-structure">(Bonus) Step 15: Using a Reasonable Directory Structure</h3>
<p>This step is totally optional, and it has nothing to do with the function of the App. Just my opinion on how you should organize your files.</p>
<p>So as you can probably guess, stuffing your Actions into the same file as your Components, and having a single reducer for your entire App, does not scale very nicely when your App grows. Here is my suggested file structure:</p>
<pre><code>app|-- javascript   |-- actions      |-- index.js      |-- things.js   |-- components   |-- packs   |-- reducers      |-- index.js      |-- things.js
</code></pre><h3 id="heading-bonus-mar-17-2019-update-step-16-install-typescript">(Bonus — Mar 17 2019 Update) Step 16: Install Typescript!</h3>
<p><a target="_blank" href="https://github.com/Microsoft/TypeScript">Typescript</a> is just like Javascript but with types! It is described as a “<a target="_blank" href="https://en.wikipedia.org/wiki/TypeScript">strict syntactical superset of Javascript</a>”, meaning that Javascript is considered valid Typescript, and the “type features” are all optional.</p>
<p>IMO Typescript is fantastic for large Javscript projects, such as a big React front-end. Below are instructions on how to install it, and a small demo of it inside our project.</p>
<p>First, run the following commands (taken from the <a target="_blank" href="https://github.com/rails/webpacker/blob/master/docs/typescript.md">Webpacker Readme</a>):</p>
<pre><code>bundle exec rails webpacker:install:typescriptyarn add @types/react @types/react-dom
</code></pre><p>Now, to see it in action, let’s rename <code>app/javascript/reducers/things.js</code> to <code>things.tsx</code> and add the following lines to the top of the file:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/avtizC4rc2F9o8vKRFOITsBU42p9clMyAuaC" alt="Image" width="800" height="523" loading="lazy">
<em>Lets add an interface to tell Typescript what “Thing” should be</em></p>
<p>After you add <code>interface Thing</code> , let’s use it by having <code>const initialState</code> use that type (seen in the screenshot above), and specify that <code>thingsReducer</code> return an array of type <code>Thing</code> (also seen in the screenshot).</p>
<p>Everything should still work, but to see Typescript in action, lets add a <code>default</code> case to <code>thingsReducer</code> and add <code>return 1</code> . Since <code>1</code> is not a <code>Thing</code> type we will see the output of <code>./bin/webpack-dev-server</code> fail with the following:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/AZ8YigkTdjeGHWLoG62dLsJ7Ksst3jqlEj43" alt="Image" width="800" height="396" loading="lazy">
<em>Type Thing being enforced in our code</em></p>
<p>And that’s it! You can now add Typescript <code>.tsx</code> files to your project and start using Types with your project.</p>
<p><a target="_blank" href="https://stackoverflow.com/a/35048303/1176788">Here’s a great overview of Typescript and why you should use it</a>.</p>
<h3 id="heading-the-end">The End</h3>
<p>You made it! You’ve made a Rails App that uses React and Redux. That’s pretty much it for the tutorial. I hope you had fun and learned something along the way.</p>
<p>If you build something with React and Rails, please do share it in the comments below — along with any questions or comments you may have for me.</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to set up server-side rendering in React with Rails using Puppeteer ]]>
                </title>
                <description>
                    <![CDATA[ By Sitaram Shelke This post is co-authored by Hricha Kabir, my colleague at Altizon Systems. She was working on this task primarily. I had the chance to learn along the way. _Photo by [Unsplash](https://unsplash.com/@rvruggiero?utm_source=medium&utm... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/server-side-rendering-react-with-rails-using-puppeteer-cf5ec2697e88/</link>
                <guid isPermaLink="false">66c35e92b8711219e1e72def</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ puppeteer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 21 Feb 2019 06:00:04 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*JDwIoDI39Uzjzp5c" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sitaram Shelke</p>
<p>This post is co-authored by <a target="_blank" href="https://in.linkedin.com/in/hrichakabir">Hricha Kabir</a>, my colleague at <a target="_blank" href="http://www.altizon.com">Altizon Systems</a>. She was working on this task primarily. I had the chance to learn along the way.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SFMTJgWJQqSDFXU-rUJrn4HkgCccugY1GpYh" alt="Image" width="800" height="533" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@rvruggiero?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="_blank" title=""&gt;Robert V. Ruggiero on &lt;a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="<em>blank" title=")</em></p>
<p>We work on an IoT product focusing on manufacturing industries and build analytics reports. Most of the time, report design and information vary based on the user’s role who is going to consume it.</p>
<p>Example: A Director level person is interested in a consolidated report of a week, whereas a Department Head is interested in the statistics of a single day and Quality Manager is keen about shift data. If we further drill down the hierarchy, then the Production Manager will be the one who wants to look into live production data.</p>
<p>For live data, Production manager can open the Live Dashboard and monitor it, but the user who wants to see a consolidated report won’t prefer to login into Product and check out a report. Instead, they prefer scheduled email communication which will send a report based on scheduled time and repeat it forever until unless a user stopped this scheduled job.</p>
<p>So our task was to write a utility which periodically sends a particular report to a user via email on a daily basis or at a defined scheduled time. For scheduling, we use <a target="_blank" href="https://sidekiq.org/">Sidekiq</a>, but our main challenge was: how to execute/calculate the report on the server side (without opening a browser) and send it over email.</p>
<p>In all of our products, we use <strong>React</strong> for the front-end and it does the heavy lifting of rendering the report on the browser. To achieve attaching the same report in the email, we would have to design an HTML template for every report. That means we would have had 2 views of each report, one written in HTML and another in ReactJS.</p>
<p>This has following drawbacks:</p>
<p><strong>1.</strong> The product code base will have duplicate code which violates the DRY principle for software development.</p>
<p><strong>2.</strong> Increases the time for designing a report which impacts product delivery.</p>
<p>We decided to look at other possible solutions instead of writing the same code twice. And we came across following options and explored them one by one until we succeeded in achieving our goal.</p>
<p><strong>1. Print Screen:</strong> Print the report using print screen and send it as an attachment.</p>
<p><strong>2. FrontEnd Print Button:</strong> In report’s UI, add a Print Button which will convert react component into HTML/PDF page.</p>
<p><strong>3. Ruby Gem:</strong> There is a ruby gem which can render a report component on the server side within Rails, generate its HTML and send it as an email body.</p>
<p><strong>4. Server-Side Rendering with Node server:</strong> Use serverside rendering using ReactDOMServer and <a target="_blank" href="https://developers.google.com/web/updates/2017/04/headless-chrome">headless</a> browser protocol to render HTML and JS and generate a pdf.</p>
<p>Now we will go through the details of each solution.</p>
<h4 id="heading-print-screen"><strong>Print Screen:</strong></h4>
<p>It was the simplest solution we had and it requires user input. A user needs to be present with a system who will do a screen capture as an image and attach it over the mail. But this doesn’t scale. Also what if a user wants a report at a scheduled time or sent periodically?</p>
<p>Example<strong>:</strong> Every week at 8 pm. It’s not possible for a person to do this. This also suffers from the inability to fully capture a scrollable page, so we had to drop this idea.</p>
<h4 id="heading-frontend-print-button"><strong>FrontEnd Print Button:</strong></h4>
<p>After doing some search, we found out there are some browser extensions available which produce a full image of an opened page. Example: Full Page Screen Capture in Chrome. After adding this extension to the browser, we would be able to capture any screen in image(png/jpg) format.</p>
<p>Again this solution requires no development but suffers from some of the previous scaling and scheduling issues. At the same time, we would still need a user logged in to the browser to perform this action, which defeats the purpose of email delivery.</p>
<h4 id="heading-rubygem"><strong>RubyGem:</strong></h4>
<p>Soon we realized that our solution cannot require browser interaction. We would need to use <a target="_blank" href="https://alligator.io/react/server-side-rendering/">server-side rendering</a>. So we started exploring Ruby Gems which support server-side rendering with React. We explored the following Gems</p>
<p><strong>3.1 <a target="_blank" href="https://github.com/aaronvb/rails_react_stdio">rails_react_stdio</a>:</strong></p>
<p>It is based on <a target="_blank" href="https://github.com/ReactTraining/react-stdio">react-stdio</a> which supports server-side rendering irrespective of server-side technology. It acts as a binary which will do the work of rendering react components. For rendering React Component on the server side we need to pass the file path of the react component and props if required. It will return a JSON response which will have the HTML code of the report. Further we can send HTML content over email.</p>
<p>Internally this gem uses <em>popen3</em> for executing render command. But this means that <em>react-stdio</em> binary needs to be present in the docker container where our rails app is running.</p>
<p>This is not great from a point of view of maintainability and reproducibility. Additionally having large HTML content with charts can be slow to load so we preferred pdf attachment. Yet we gave it a try.</p>
<p>Example<strong>:</strong> For rendering a report which has the component <em>TestComponent</em> and the file path <em>app/assets/javascripts/components/TestComponent.jsx</em></p>
<p>First, include the gem in Gemfile:</p>
<pre><code class="lang-rb">gem ‘rails_react_stdio’, ‘~&gt; <span class="hljs-number">0</span>.<span class="hljs-number">1.0</span>’
</code></pre>
<p>Now from the email scheduler call the gem method to render the report and get the HTML from the response. Then send this response to email.</p>
<pre><code class="lang-rb">email_body = RailsReactStdio::React.render(‘app/assets/javascripts/components/TestComponent.jsx’, {<span class="hljs-symbol">city:</span> “Pune”})
</code></pre>
<p>We tried using the above method but had no success. Also the GitHub repo was not actively maintained, and all of its test cases were failing. So we decided to move forward without this.</p>
<p><strong>3.2 react-rails:</strong></p>
<p>The ReactJS community built this gem. It uses <a target="_blank" href="https://github.com/rails/execjs">ExecJS</a> for executing render-action of a react component on the server side. We just need to pass one flag <em>‘prerender’: true</em>.</p>
<pre><code class="lang-js">&lt;%= react_component(‘Dashboard’, {<span class="hljs-attr">name</span>: ‘Example’}, {<span class="hljs-attr">prerender</span>: <span class="hljs-literal">true</span>}) %&gt;
</code></pre>
<p>This prerendering process does not have access to the window or document so it does not load runtime JavaScript or CSS. We also use JQuery for a few things so it wouldn’t work as well.</p>
<p>There is an alternative: this gem has another class for server-side rendering, <em>ExecJSRenderer</em>, which helps in availing JavaScript to a component on the server side.</p>
<p><em>ExecJSRenderer</em> Class has 2 methods: _before<em>render</em> and _after<em>render,</em> which gives access to the JavaScript required before and after component rendering. But it’d require a lot of changes in the existing code base for supporting server-rendering, in every controller. Apart from this, ExecJS doesn’t provide sandboxing as well as runtime error information. We were still looking for something better.</p>
<h4 id="heading-server-side-rendering-with-node-server"><strong>Server-Side Rendering with Node server:</strong></h4>
<p>Most of the ruby gems we explored internally created the node server and rendered react on the server side. So instead of using Ruby, we decided to directly use the node server and achieve this task ourselves.</p>
<p><strong>4.1 ReactDOMServer based solution:</strong></p>
<p>Here we use <a target="_blank" href="https://reactjs.org/docs/react-dom-server.html">ReactDOMServer</a>. It is the preferred solution for server-side rendering from the React team. We created a node server which calls the <em>renderToString()</em> method with a react component. It returns the rendered content which we combine with HTML and send over email.</p>
<p>Example<strong>:</strong></p>
<pre><code class="lang-js">server.get(‘/’, <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-comment">/**
  * renderToString() will take our React app and turn it into a      string
  * to be inserted into our Html template function.
  */</span>
  <span class="hljs-built_in">console</span>.log(‘started’)
  <span class="hljs-keyword">const</span> body = renderToString(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>);
  <span class="hljs-keyword">const</span> title = ‘Server side Rendering React Components’;
  <span class="hljs-keyword">var</span> result = Html({ body, title })
}
</code></pre>
<p>The <em>renderToString()</em> method returns a string response. We pass this response to an HTML template and send the template over mail.</p>
<p>When we tested this out, an email was received as expected except all the images used in the report were broken. The email was not able to resolve the image source relative path.</p>
<p>To get the correct images in the email, we would either need to</p>
<ul>
<li>Store images in S3 and use the source URL in the report: So now we would be adding S3 image URLs in the email, and the email server would directly load images from the S3 server. It would require extra cloud space for storing images, and downloading from destination requires another network call from the email inbox.</li>
</ul>
<p>Or</p>
<ul>
<li>Send base64 code of image in the mail: Instead of image URL, we can send the base64 code of an image. Although It increases network payload, many mail servers such as Outlook and Gmail block base64 images.</li>
</ul>
<p>So we would still need to do something about this.</p>
<p><strong>4.2 <a target="_blank" href="https://github.com/GoogleChrome/puppeteer">Puppeteer</a>:</strong></p>
<p>After exploring the above methods, we discovered Puppeteer Headless Chrome service. Puppeteer is a NodeJS library from the Google Chrome team, used in end to end testing. By default, it uses the Chrome/Chromium browser for the same. Essentially it simulates all the actions a user can perform in the browser. Example: Keyboard Input, Mouse events, Form submission etc.</p>
<p>The result of a puppeteer request can be an HTML page, Screenshot, or PDF. In case of HTML, it renders the full page on the server side along with all images, CSS, and JavaScript. Or a user can render a page on the server side and if required they can generate a screenshot or a pdf.</p>
<p>If we use this library with a Node server, we can schedule a task within Sidekiq which would make a request to this server, render a report, and send it over email. Puppeteer also has a rich set of APIs which support in sending customizing headers in the request which help us in authenticating a background request.</p>
<p>This is exactly what we needed!</p>
<p><strong>So the overall request lifecycle inside puppeteer should look like this:</strong></p>
<p><strong>1.</strong> It launches the browser</p>
<p><strong>2.</strong> Creates a page on the browser</p>
<p><strong>3.</strong> Authenticate with the Report Application server</p>
<p><strong>4.</strong> Opens the report URL that the user wants and returns the rendered page content</p>
<p><strong>5.</strong> Based on the user’s requirement, stores HTML of the rendered page or takes a Screenshot or generates a PDF.</p>
<p>We can use either the default browser (gets downloaded when we install puppeteer) or we can give a specific browser version. If we give a specific browser version, then we will have to make sure that puppeteer APIs are compatible with the given browser.</p>
<p>All of the above can be achieved using the following steps.</p>
<p><strong>1. Install puppeteer:</strong></p>
<p>It downloads the default Chrome/Chromium browser. So If we want to launch the default browser and install puppeteer:</p>
<pre><code class="lang-bash">npm install puppeteer
</code></pre>
<p><strong>2. Serve a Request:</strong></p>
<p>Build a server which will receive a request and implement a request lifecycle and return the desired result.</p>
<p>The following is the code snippet we use for generating a pdf of a given page URL.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> puppeteer = <span class="hljs-built_in">require</span>(“puppeteer”);
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.launch();
<span class="hljs-keyword">const</span> page = <span class="hljs-keyword">await</span> browser.newPage();
<span class="hljs-keyword">await</span> page.emulateMedia(“screen”);
<span class="hljs-keyword">await</span> page.goto(‘https:<span class="hljs-comment">//www.google.com', {</span>
      timeout: <span class="hljs-number">30</span> * <span class="hljs-number">1000</span>, 
      <span class="hljs-attr">waitUntil</span>: “networkidle0”
});
<span class="hljs-keyword">await</span> page.pdf(pdfOptions);
<span class="hljs-keyword">return</span> page;
</code></pre>
<p>As we already mentioned in the lifecycle steps above, it first launches the browser. Then it creates and opens a page in the launched browser. Here along with the URL, we have passed <em>timeout</em> and <em>waitUntil</em> params which are given for the following reasons:</p>
<ul>
<li><em>timeout</em>: If we want to restrict a request time then we can pass it to timeout variable</li>
<li><em>waitUntil</em>: if networkidle0 is given, then the next request will not be served until or unless the current one is completed.</li>
</ul>
<p>In the end, rendered content will be passed to the pdf method and it will generate a pdf. We can also provide PDF formatting options like page height, page width, headers, footers, and margins.</p>
<p>Additionally, we have called page.emulateMedia(“screen”); which applies CSS to the page. If we don’t add emaulateMedia, our PDF doesn’t load the CSS.</p>
<p>Apart from what we have used, there are many different configuration options with Puppeteer APIs. Visit the <a target="_blank" href="https://github.com/GoogleChrome/puppeteer/blob/v1.12.2/docs/api.md#">API docs</a> for more information.</p>
<p>If you found this helpful or if you have any suggestions, please feel free to write them it in comments.</p>
<p>That’s all folks.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to deploy a Rails 5.2 PostgreSQL app on AWS Elastic Beanstalk ]]>
                </title>
                <description>
                    <![CDATA[ By Evrim Persembe It’s official, using Heroku for all my Rails projects so far has spoiled me rotten. After receiving some AWS credits thanks to a pitch competition, I decided to deploy my latest project on Elastic Beanstalk (AWS’ Heroku competitor).... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-a-rails-5-2-postgresql-app-on-aws-elastic-beanstalk-34e5cec3a984/</link>
                <guid isPermaLink="false">66c3517af41767c3c96bad15</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ postgres ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 28 Nov 2018 00:00:00 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*OciaQvyAjhVdws2DUeYgCw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Evrim Persembe</p>
<p>It’s official, using <a target="_blank" href="https://heroku.com/">Heroku</a> for all my Rails projects so far has spoiled me rotten. After receiving some AWS credits thanks to a pitch competition, I decided to deploy my latest project on <a target="_blank" href="https://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a> (<a target="_blank" href="https://aws.amazon.com/">AWS</a>’ Heroku competitor). All I have to say is that I miss Heroku.</p>
<p>Alas, if you are in a similar situation, here are step-by-step instructions to deploying your Rails 5.2 / PostgreSQL app on Elastic Beanstalk.</p>
<h3 id="heading-installing-the-elastic-beanstalk-cli">Installing the Elastic Beanstalk CLI</h3>
<p>We will use the terminal in this tutorial. Let’s begin with installing the “Elastic Beanstalk Command Line Interface.” Here is how to do it on macOS using <a target="_blank" href="https://brew.sh/">Homebrew</a>:</p>
<pre><code>brew install awsebcli
</code></pre><p>If you are using another platform, googling “how to install awsebcli on [your platform]” should lead you in the right direction.</p>
<h3 id="heading-initializing-elastic-beanstalk">Initializing Elastic Beanstalk</h3>
<p>I will assume that you already have an Amazon Web Services account, if not go ahead and create one. Now, go into the directory of your project, and initialize Elastic Beanstalk:</p>
<pre><code>cd my_projecteb init
</code></pre><p>Then the EB CLI will ask you a few questions to initialize the Elastic Beanstalk application. The initialization part is straightforward. If you get stuck anywhere you can check out the <a target="_blank" href="https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-configuration.html">“Configure the EB CLI”</a> page from the documentation.</p>
<h3 id="heading-creating-a-new-environment">Creating a new environment</h3>
<p>As you already know, your application can have many environments (think of them as different configurations). For example, you might have a “production” environment. This is the environment that you use for the user-facing version of your app. But you might want to have another environment named “staging.” This is where you try new versions of your app, before pushing it to the production environment.</p>
<p>We can create an environment using the command below:</p>
<pre><code>eb create production
</code></pre><h3 id="heading-deploying-to-elastic-beanstalk">Deploying to Elastic Beanstalk</h3>
<p>Assuming you are using Git, commit your changes before deploying your application. The EB CLI deploys your last commit. If you deploy before committing, you will deploy an earlier version of your app.</p>
<p>After committing your changes, deploy using the following:</p>
<pre><code>eb deploy
</code></pre><p>So far so good, now we need to set a few things before our app actually starts working.</p>
<h3 id="heading-setting-up-the-master-key">Setting up the master key</h3>
<p>You can use the CLI for this purpose as well, but I prefer using the web panel for this. Here is how:</p>
<ol>
<li>Go to AWS, choose “Services -&gt; Elastic Beanstalk,” then click on your environment.</li>
<li>Open the “Configuration” tab, and click “Modify” under the box titled “Software.”</li>
<li>Under “Environment properties,” add a new key named <code>RAILS_MASTER_KEY</code>. Set its value to the content of your “master.key” file. You can find this file in the “config” directory of your Rails app.</li>
<li>Click on the “Apply” button at the bottom of the page.</li>
</ol>
<h3 id="heading-setting-up-a-postgresql-database">Setting up a PostgreSQL database</h3>
<p>Elastic Beanstalk provides an easy way to set up a database, which you can reach through “Configuration -&gt; Database.” I prefer not to use that because if you need to rebuild your Elastic Beanstalk environment, your database will be deleted. So, we will set up the database separate from our Elastic Beanstalk environment.</p>
<h4 id="heading-creating-a-postgresql-database-on-rds">Creating a PostgreSQL database on RDS</h4>
<ol>
<li>Go to AWS, choose “Services -&gt; RDS.”</li>
<li>Choose “Create database.”</li>
<li>Choose “PostgreSQL,” and click “Next.”</li>
<li>Select your use case, “Production” or “Dev/Test,” and click “Next.”</li>
<li>Here, you can try different options, and see what the estimated monthly costs are. Settle with something that is within your budget. You can start with a <code>db.t2.micro</code> instance, no multi-AZ deployment and a general purpose SSD.</li>
<li>Choose an instance identifier, this is sort of a “namespace.”</li>
<li>Choose a username and password, keep these handy for now, click “Next.”</li>
<li>On the “Configure advanced settings” section, the important thing is the security groups. Select “Choose existing VPC security groups,” and select the security group that looks like “…-AWSEBSecurityGroup-…”</li>
<li>Pick a database name, such as <code>my_app_production</code>.</li>
<li>Click on “Create database,” this will take a while.</li>
</ol>
<h4 id="heading-allowing-access-to-the-database">Allowing access to the database</h4>
<p>In the meantime, let’s add Postgres access to your security group:</p>
<ol>
<li>Go to AWS, choose “Services -&gt; EC2.”</li>
<li>Click on “Security Groups” on the left panel.</li>
<li>Choose the security group from the previous section.</li>
<li>Go to the “Inbound” tab, and click on “Edit.”</li>
<li>Click on “Add Rule.” For “Type,” choose “PostgreSQL,” and for “Source” type in the ID of the security group that you are adding this rule to. It should be right above the “Inbound” tab and should look like <code>sg-*</code>.</li>
<li>Click “Save.”</li>
</ol>
<h4 id="heading-setting-up-the-production-database-configuration">Setting up the production database configuration</h4>
<p>Now, in your Rails directory, open <code>config/database.yml</code>. Change it as such:</p>
<pre><code># ...
</code></pre><pre><code>production:  &lt;&lt;: *<span class="hljs-keyword">default</span>  database: &lt;%= ENV[<span class="hljs-string">'RDS_DB_NAME'</span>] %&gt;  username: &lt;%= ENV[<span class="hljs-string">'RDS_USERNAME'</span>] %&gt;  password: &lt;%= ENV[<span class="hljs-string">'RDS_PASSWORD'</span>] %&gt;  host: &lt;%= ENV[<span class="hljs-string">'RDS_HOSTNAME'</span>] %&gt;  port: &lt;%= ENV[<span class="hljs-string">'RDS_PORT'</span>] %&gt;
</code></pre><h4 id="heading-adding-relevant-environment-variables-to-elastic-beanstalk">Adding relevant environment variables to Elastic Beanstalk</h4>
<p>We told Rails to get the information for the production database using the above environment variables. Now we need to make sure that our Elastic Beanstalk environment includes these variables:</p>
<ol>
<li>Go to AWS, choose “Services -&gt; Elastic Beanstalk,” then click on your environment.</li>
<li>Open the “Configuration” tab, and click “Modify” under the box titled “Software.”</li>
<li>Under “Environment properties,” add the following key-value pairs:</li>
<li><code>RDS_DB_NAME</code>: Database name you picked when setting up your database.</li>
<li><code>RDS_USERNAME</code>: Username you picked when setting up your database.</li>
<li><code>RDS_PASSWORD</code>: Password you picked when setting up your database.</li>
<li><code>RDS_HOSTNAME</code>: Go to “Services -&gt; RDS,” and you can find this information under the “Connect” section of your database instance information page. It is called “Endpoint.”</li>
<li><code>RDS_PORT</code>: Set this to 5432.</li>
<li>Click on the “Apply” button at the bottom of the page.</li>
</ol>
<p>After this, commit your Rails app directory again, and run <code>eb deploy</code>. You might want to wait a few minutes before doing this because Elastic Beanstalk does some stuff in the background after updating environment variables.</p>
<p>After these steps, your Rails app “should” be running.</p>
<h3 id="heading-still-not-working">Still not working?</h3>
<p>If there are any issues, you can go to your EB environment on the AWS web panel, click on “Logs,” and choose “Request Logs -&gt; Last 100 Lines” to see the logs. But before doing that, I’d recommend trying to run your Rails app using the production environment on your local machine by using the comma<code>nd rails s RAILS_ENV=product</code>ion.</p>
<p>I’ll be the first to admit that I’m not the most experienced person when it comes to deployment. As I said, I always used Heroku in the past, and I probably will use it for my future projects as well. These steps worked for me after a few days of scratching my head trying to set up my Rails app on Elastic Beanstalk, so I wanted to share these in hopes of saving time for people who are in the same situation I was. So, take this all with a grain of salt, and good luck!</p>
<p>If you like this article, <a target="_blank" href="https://twitter.com/evrimfeyyaz">follow me on Twitter</a> or <a target="_blank" href="https://evrim.us12.list-manage.com/subscribe/post?u=7d6b207df0db42f6bfcff3322&amp;id=70b8425aa4">sign up to my newsletter</a> to get notified when I write new articles. I write about software and startups.</p>
<p><strong>If you are looking for a Rails developer, I’m currently available for remote work. Feel free to get in touch with me at hi{at}evrim.io.</strong></p>
<p><em>Originally published at <a target="_blank" href="https://evrim.io/deploying-a-rails-52-postgresql-app-on-aws-elastic-beanstalk/">evrim.io</a> on November 28, 2018.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to store translations inside a database with Globalize ]]>
                </title>
                <description>
                    <![CDATA[ By Anastasia In one of my previous articles, I talked about the process of internationalizing Rails applications. That article explained all I18n basics, but it was revolving around placing all translations inside YAML files. There is nothing wrong w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-store-translations-inside-a-database-with-globalize-63cd033e29e6/</link>
                <guid isPermaLink="false">66c354eadae03919d93dc01a</guid>
                
                    <category>
                        <![CDATA[ Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ startup ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ translation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 16 Nov 2018 10:01:23 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*m8n4yc-F8Ln4EcnbL3H-CQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Anastasia</p>
<p>In one of my previous articles, I talked about the process of <a target="_blank" href="https://blog.lokalise.co/rails-i18n/">internationalizing Rails applications</a>. That article explained all <a target="_blank" href="https://guides.rubyonrails.org/i18n.html">I18n</a> basics, but it was revolving around placing all translations inside YAML files. There is nothing wrong with this approach, but unfortunately it does not always work.</p>
<p>Suppose your website has lots of user-generated content which should be adapted for different languages. I propose that you <em>store your translations inside the database.</em> Why will YAML files not work in this case?</p>
<ul>
<li>The content itself may be quite large and it would be inconvenient to store it inside a file</li>
<li>The content is dynamic and users should be able to create translated versions themselves, without the help of the site’s developer</li>
</ul>
<p>It appears that the I18n module <a target="_blank" href="https://guides.rubyonrails.org/i18n.html#using-different-backends">allows you to define a custom backend</a> that, for instance, may be powered by ActiveRecord. Luckily, there is no need to craft your own solution as there is already an existing one: <a target="_blank" href="https://github.com/globalize/globalize">Globalize</a>. Globalize is a battle-tested library characterized as “Rails I18n de-facto standard library for ActiveRecord model/data translation.” With its help you can easily translate model attributes, scope them, introduce fallbacks, and so on.</p>
<p>So, in this article we are going to talk about Globalize and see it in action by creating a sample Rails application. Shall we start?</p>
<h3 id="heading-preparing-the-application">Preparing the Application</h3>
<p>Let’s get started by generating a new Rails app:</p>
<pre><code>rails <span class="hljs-keyword">new</span> GlobalizeSample
</code></pre><p>I’ll assume you are using <em>Rails 5.2.1</em> for this demo but still the described concepts apply to earlier versions as well.</p>
<p>Let’s suppose we are building an <a target="_blank" href="https://www.shopify.com/plus">international online shop</a> showcasing various products. These products will be added by the administrator, and so we can’t know what the content will be ahead of the game. This means that the traditional method of using YAML files to store translations won’t work. Our content manager will have access to the CMS only, and we would rather not give them access to the source code of the app (I shudder to think about it!).</p>
<p>But, fear not, in the next section we will overcome this problem easily. For now, however, let’s take care of the basics.</p>
<h3 id="heading-administering-products">Administering Products</h3>
<p>Utilize code generator and create a new scaffold for the <code>Product</code>:</p>
<pre><code>rails g scaffold Product title:string description:text
</code></pre><p>This should create a model, controller, routes, and views for the products. Don’t forget to run the migration:</p>
<pre><code>rails db:migrate
</code></pre><p>Now start the server:</p>
<pre><code>rails s
</code></pre><p>Visit the <code>http://localhost:3000/products</code> path and make sure that you are able to add, modify, and delete the products.</p>
<h3 id="heading-switching-the-language">Switching the Language</h3>
<p>In order to see the Globalize library in action, we will need a way to switch the app’s locale. I won’t cover this process in detail (as we have a <a target="_blank" href="https://blog.lokalise.co/rails-i18n/">separate article on the topic</a>) so let’s do it quickly.</p>
<p>First, add the list of supported locales to the <code>config/application.rb</code>:</p>
<pre><code># ... config.i18n.available_locales = [:en, :ru]
</code></pre><p>I will be supporting English and Russian, but you may choose any other languages.</p>
<p>Next, tweak the <code>config/routes.rb</code> and wrap the product resource with a scope. Also, while we are here, add a root route:</p>
<pre><code>scope <span class="hljs-string">"(:locale)"</span>, <span class="hljs-attr">locale</span>: <span class="hljs-regexp">/#{I18n.available_locales.join("|")}/</span> <span class="hljs-keyword">do</span> # &lt;== add <span class="hljs-built_in">this</span> resources :products root <span class="hljs-string">'products#index'</span> # &lt;== add <span class="hljs-built_in">this</span> end # &lt;== add <span class="hljs-built_in">this</span>
</code></pre><p>After that, modify the <code>application_controller.rb</code> file:</p>
<pre><code># ... before_action :set_locale private def set_locale I18n.locale = extract_locale || I18n.default_locale end def extract_locale parsed_locale = params[:locale] I18n.available_locales.map(&amp;:to_s).include?(parsed_locale) ? parsed_locale : nil end def default_url_options { <span class="hljs-attr">locale</span>: I18n.locale } end
</code></pre><p>This code will set the locale on every request while making sure the chosen language is actually supported. Also, it will add a <code>locale</code> GET param to each link generated with the <code>link_to</code> helper.</p>
<p>Lastly, add two links to the application layout:</p>
<pre><code>&lt;!-- views/layouts/application.html.erb --&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">link_to</span> '<span class="hljs-attr">English</span>', <span class="hljs-attr">root_path</span>(<span class="hljs-attr">locale:</span> <span class="hljs-attr">:en</span>) %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">link_to</span> 'Русский', <span class="hljs-attr">root_path</span>(<span class="hljs-attr">locale:</span> <span class="hljs-attr">:ru</span>) %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
</code></pre><p>To ensure that this new feature works, add translation for the Products page title:</p>
<pre><code># config/locales/en.yml en: products: index: title: Our Products
</code></pre><pre><code># config/locales/ru.yml ru: products: index: title: Наши продукты
</code></pre><p>Now simply utilize these translations inside the <code>views/products/index.html.erb</code>:</p>
<pre><code>&lt;!-- ... --&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">t</span> '<span class="hljs-attr">.title</span>' %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span> &lt;!-- ... --&gt;
</code></pre><p>Note that we can take advantage of the “lazy lookup” because the translation keys were named in the proper way.</p>
<p>Translate other static content as necessary, then reload the server, and make sure that the locale can be properly switched. Great!</p>
<h3 id="heading-globalize-globalize-it-hard">Globalize, Globalize it Hard!</h3>
<h4 id="heading-defining-attributes-for-translation">Defining Attributes For Translation</h4>
<p>Okay, the ground work is done and we may proceed to the next part. Before Globalize can get into the game, it should be added to the <code>Gemfile</code>:</p>
<pre><code># ... gem <span class="hljs-string">'globalize'</span>, <span class="hljs-attr">git</span>: <span class="hljs-string">'https://github.com/globalize/globalize'</span>
</code></pre><p>At the time of writing this article, the stable version was not yet compatible with Rails 5.2, so we have to install directly from the <code>master</code> branch. Also note that the latest stable does not support ActiveRecord 4.1 and below, therefore <a target="_blank" href="https://github.com/globalize/globalize#installation">refer to the documentation</a> to learn which Globalize version to use for older AR.</p>
<p>Next, you have to decide which model attributes will be translated with Globalize. We are going to translate both <code>:title</code> and <code>:description</code> so list them in the model in the following way:</p>
<pre><code># models/products.rb # ... translates :title, :description
</code></pre><p>This will allow you to store store translations inside the database per locale. To make it work, however, you also need to create a special <em>translation table</em>.</p>
<h4 id="heading-translation-table">Translation Table</h4>
<p>So, if you are creating a new model and a migration, things are as simple as using a <code>create_translation_table!</code> method as <a target="_blank" href="https://github.com/globalize/globalize#creating-translation-tables">explained here</a>. Our case is a bit more complex, because we already have a <code>products</code> table with some data. Therefore it is required to move these data to the translation table. Start by generating a new migration:</p>
<pre><code>rails g migration translate_products
</code></pre><p>Now flesh it out with the following code:</p>
<pre><code># db/migrate/xyz_translate_products.rb <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TranslateProducts</span> &lt; <span class="hljs-title">ActiveRecord</span>::<span class="hljs-title">Migration</span>[5.2] <span class="hljs-title">def</span> <span class="hljs-title">change</span> <span class="hljs-title">reversible</span> <span class="hljs-title">do</span> |<span class="hljs-title">dir</span>| # &lt;</span>=== <span class="hljs-number">1</span> dir.up <span class="hljs-keyword">do</span> Product.create_translation_table!({ # &lt;=== <span class="hljs-number">2</span> title: :string, # &lt;=== <span class="hljs-number">3</span> description: :text }, { <span class="hljs-attr">migrate_data</span>: <span class="hljs-literal">true</span>, # &lt;=== <span class="hljs-number">4</span> remove_source_columns: <span class="hljs-literal">true</span> # &lt;=== <span class="hljs-number">5</span> }) end dir.down <span class="hljs-keyword">do</span> Product.drop_translation_table! migrate_data: <span class="hljs-literal">true</span> # &lt;=== <span class="hljs-number">6</span> end end end end
</code></pre><p>I’ve pinpointed the main things to note about this code:</p>
<ol>
<li>This is going to be a reversible migration.</li>
<li>We are creating a translation table for the <code>Product</code>.</li>
<li>Carefully list all the fields that should be translated as well as their types. As you recall, these fields were passed to the <code>translates</code> method inside the model.</li>
<li>Don’t forget to provide the <code>migrate_data</code> option that should preserve your original database records.</li>
<li><code>remove_source_columns</code> will ensure that the original columns (<code>:title</code> and <code>:description</code>) will be removed from the <code>products</code> table. You may also perform this step later in a separate migration.</li>
<li>That’s the action to perform when the migration is rolled back. Data should be preserved as well.</li>
</ol>
<p>Run the migration:</p>
<pre><code>rails db:migrate
</code></pre><p>After this command finishes its job, you will see a new <code>product_translations</code> table:</p>
<p>As you see, there is a <code>product_id</code> column that establishes relation to the product, and also a <code>locale</code> field to denote which language this translation is for. When you migrate your original data, it will be associated with the app’s default locale (which is English in our case). Override this behavior by using a <code>with_locale</code> method, for example:</p>
<pre><code>I18n.with_locale(:ru) <span class="hljs-keyword">do</span> Post.create_translation_table!(...) end
</code></pre><p>If you need to add more translated fields to the table later, utilize an <code>add_translation_fields!</code> method <a target="_blank" href="https://github.com/globalize/globalize#adding-additional-fields-to-the-translation-table">as shown in this example</a>. Also, don’t forget to define these new fields in the model.</p>
<h4 id="heading-try-it">Try It!</h4>
<p>At this point Globalize is integrated into our application and ready to get rolling! Perform the following steps to see it in action:</p>
<ul>
<li>Reload your server and try to create a new product: its title and description will be provided for the currently set locale only (English in my case).</li>
<li>Switch to Russian locale and make sure that both title and description are missing for the new product.</li>
<li>Edit this product and enter values for the Russian version of the product.</li>
</ul>
<p>As a result you should see two translations being stored inside the <code>product_translations</code> table:</p>
<p>Great job!</p>
<h3 id="heading-some-more-globalize-features">Some More Globalize Features</h3>
<h4 id="heading-fallbacks">Fallbacks</h4>
<p>What happens if Globalize cannot find translated attributes for the given locale? As we’ve seen in the previous section, by default it will return blank values (which are actually <code>nil</code>s). However, it is possible to enable <a target="_blank" href="https://github.com/globalize/globalize#i18n-fallbacks-for-empty-translations">I18n fallbacks</a> and display attribute values from another locale. To achieve that, just turn fallbacks on inside the <code>config/application.rb</code> file:</p>
<pre><code># ... config.i18n.fallbacks = <span class="hljs-literal">true</span>
</code></pre><p>Now when the translated attribute is <code>nil</code>, Globalize will try to load values from another locale. To make sure this feature is working, reload the server, create a new product, and then switch to another language. The title and description should fallback to another locale.</p>
<p>If you would like to employ fallbacks when the translation values are also blank (not <code>nil</code>), set the <code>fallbacks_for_empty_translations</code> option to <code>true</code>:</p>
<pre><code># models/product.rb # ... translates :title, :description, <span class="hljs-attr">fallbacks_for_empty_translations</span>: <span class="hljs-literal">true</span>
</code></pre><p>Also note that it is possible to define a custom fallback chain globally in the following way:</p>
<pre><code># somewhere <span class="hljs-keyword">in</span> an initializer Globalize.fallbacks = {:<span class="hljs-function"><span class="hljs-params">en</span> =&gt;</span> [:de, :ru]}
</code></pre><h4 id="heading-scope-and-context">Scope and Context</h4>
<p>Globalize provides a special model scope called <code>with_translations</code> that can be used to load translation for a given language. In this example we are loading all translations for the English locale only:</p>
<pre><code>Product.with_translations(<span class="hljs-string">'en'</span>)
</code></pre><p>On top of that, it is possible to display translation for a desired locale in your views. To achieve that, use a <code>with_locale</code> method:</p>
<pre><code>&lt;% Globalize.with_locale(:en) <span class="hljs-keyword">do</span> %&gt; &lt;!-- render your stuff here... --&gt; &lt;% end %&gt;
</code></pre><h4 id="heading-interpolation">Interpolation</h4>
<p>What’s interesting is that Globalize even supports interpolation in the translated attributes. It works in the same way as interpolation in YAML translation files:</p>
<pre><code>product.title = <span class="hljs-string">"Product for %{someone}"</span> product.title someone: <span class="hljs-string">"John"</span> # =&gt; <span class="hljs-string">"Product for John"</span>
</code></pre><p>So, the placeholder here is <code>%{someone}</code>. To provide its value, simply pass a hash to the proper model attribute. Really convenient!</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this section we have seen how to store translations inside database with the help of Globalize solution. We have discussed its basics, seen how to install and configure it, how to migrate data properly, how to define translations, provide fallbacks and utilize scopes. All in all, we have covered nearly everything Globalize has to offer, and so you may now apply these concepts into practice! Also don’t forget that Globalize can safely play with YAML files, so you can mix and match these approaches as you see fit.</p>
<p>Which solution do you utilize to internationalize user-generated content? Would you give Globalize a go? Share your thoughts in the comments section!</p>
<h3 id="heading-make-your-life-easier-with-lokalise">Make Your Life Easier With Lokalise</h3>
<p>Supporting multiple languages on a big website may become a serious pain. You must make sure that all the keys are translated for each and every locale. Luckily, there is a solution to this problem: the Lokalise platform that <a target="_blank" href="https://lokalise.co/features">makes working with the localization files much simpler</a>. Let me guide you through the initial setup which is nothing complex really.</p>
<ul>
<li>To get started, <a target="_blank" href="https://lokalise.co/signup">grab your free trial</a></li>
<li>Create a new project, give it some name, and set English as a base language</li>
<li>Click “Upload Language Files”</li>
<li>Upload translation files for all your languages</li>
<li>Proceed to the project, and edit your translations as needed</li>
<li>You may also contact professional translator to do the job for you</li>
<li>Next simply download your files back</li>
<li>Profit!</li>
</ul>
<p>Lokalise has many more features including support for dozens of platforms and formats, and even the possibility to upload screenshots in order to read texts from them. So, stick with Lokalise and make your life easier!</p>
<p><em>Originally published at <a target="_blank" href="https://blog.lokalise.co/store-translations-inside-database-globalize/">blog.lokalise.co</a> on November 16, 2018.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to setup TinyMCE in your Rails app using Webpack ]]>
                </title>
                <description>
                    <![CDATA[ By Joanna Gaudyn The popularity of using Webpack to deal with your assets in Rails is steadily increasing. Getting started is really straightforward. If you are starting a new app, you simply run rails new my_app --webpack and Rails takes care of the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-setup-tinymce-in-your-rails-app-using-webpack-edf030915332/</link>
                <guid isPermaLink="false">66c354b1c45f383e42e907ae</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 19 Sep 2018 07:08:22 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*5d_eDFKTmlTdYafG9dahdw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Joanna Gaudyn</p>
<p>The popularity of using Webpack to deal with your assets in Rails is steadily increasing. Getting started is really straightforward. If you are starting a new app, you simply run <code>rails new my_app --webpack</code> and Rails takes care of the rest.</p>
<p>Thanks to the <a target="_blank" href="https://github.com/rails/webpacker">webpacker gem</a>, adding Webpack to your existing application is also pretty uncomplicated. You add the gem to your Gemfile, bundle, and finally install webpacker:</p>
<pre><code>gem <span class="hljs-string">'webpacker'</span>, <span class="hljs-string">'~&gt; 3.5'</span>bundlebundle exec rails webpacker:install
</code></pre><p>This is pretty sweet. Now all you need to do is link your JavaScript pack and the CSS imported in it into the head of your <code>application.html.haml</code>:</p>
<pre><code>&lt;%= javascript_pack_tag <span class="hljs-string">'application'</span> %&gt; &lt;!-- js <span class="hljs-keyword">from</span> app/javascript/packs/application.js --&gt;
</code></pre><pre><code>&lt;%= stylesheet_pack_tag <span class="hljs-string">'application'</span> %&gt; &lt;!-- CSS imported via Wbpack --&gt;
</code></pre><p>Once this is done, you are ready to write your modern JavaScript code and make use of all the great libraries out there.</p>
<h3 id="heading-what-is-tinymce">What is tinyMCE?</h3>
<p>TinyMCE is a rich text editor in the cloud. To put it simply, it’s like Word that can be implemented into your app.</p>
<p>The project I am working on uses it to let admins edit the content of the front page. Thanks to TinyMCE, it isn’t necessary to build a separate admin interface for that purpose. But the editor’s usage can be much more versatile. Think, for example, of what Wordpress or Evernote allows you to do thanks to their build in tools.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*lUWdaoq0bkq3vDCrlzn4zQ.png" alt="Image" width="616" height="246" loading="lazy">
<em>Example use of TinyMCE. The power is in the user’s hands now.</em></p>
<h3 id="heading-usage-via-cdn">Usage via CDN</h3>
<p>We originally implemented the editor via CDN (e.g. linking the script in the head of our <code>application.html.haml</code>) like this:</p>
<pre><code>!!!%html  %head    %meta ... &lt;!-- some meta content --&gt;    %title ... &lt;!-- MyApp --&gt;    = csrf_meta_tags
</code></pre><pre><code>    %script{<span class="hljs-attr">src</span>: <span class="hljs-string">'https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=gexncjni90zx3qf0m5rr7kl8l40wd5yuly2xjza0g3kwrljt'</span>}    = stylesheet_link_tag <span class="hljs-string">'application'</span>, <span class="hljs-attr">media</span>: <span class="hljs-string">'all'</span>    = javascript_include_tag <span class="hljs-string">'application'</span>  %body    &lt;!-- the usual body stuff --&gt;
</code></pre><p>This required adding a file with our customized function in <code>app/assets/javascript/tinyMce.js</code>. Note that we are also using jQuery.</p>
<pre><code>$( <span class="hljs-built_in">document</span> ).on(<span class="hljs-string">'turbolinks:load'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
</code></pre><pre><code>    tinyMCE.init({         <span class="hljs-attr">selector</span>: <span class="hljs-string">'textarea.tinymce'</span>,             <span class="hljs-comment">// some other settings, like height, language,         // order of buttons on your toolbar etc.             plugins: [            'table', 'lists' // whatever plugins you want to add        ]    });});</span>
</code></pre><p>In addition to that, we had to include a <a target="_blank" href="https://www.tiny.cloud/download/language-packages/">translation file</a> (which is not necessary if you’re using English in your app). For everything to display correctly in production, you’ll also need to get a free <a target="_blank" href="https://apps.tiny.cloud/signup/">Tiny Cloud API key</a> .</p>
<h3 id="heading-webpack-and-tinymce">Webpack and tinyMCE</h3>
<p>Everything was working great for a couple of months, but we decided that it was time for the transition towards Webpack.</p>
<p>Webpack is supposed to make your life easier and, coupled with yarn, lets you focus on the important stuff. Say you want to use package A. It so happens, that package A relies on packages B and C. And package B depends on D, E and F. Rather than spending hours figuring out what the dependencies are and installing them all individually, what you want is to say <code>yarn add package-A</code>, and have it figured out for you. And this is <em>almost</em> the case.</p>
<p>This transition when it came to tinyMCE was way more painful than it should have been. And that’s why I decided to write this post. I hope it saves someone some time and frustration.</p>
<p><strong>If you previously had tinyMCE implemented via CDN</strong>, you’d like to get rid of some stuff, to start clean. Remove the script link from <code>application.html.haml</code>. Then comment out the content of the <code>tinyMce.js</code> file (and the language file if you’re using one). I also decided to get rid of the jQuery dependency (in our case it meant removing <code>gem 'jquery-rails'</code> from the Gemfile, and in the <code>app/assets/javascripts/application.js</code> removing <code>//= require jquery</code> and replacing <code>//= require jquery_ujs</code> with <code>//= require rails-ujs</code>).</p>
<p>Note: Proceed with caution if you have more external libraries in your project that rely on jQuery (e.g. Bootstrap or Select2). Ultimately your goal would probably be to move all of them to Webpack, but the bigger the project, the more complex that task could be, so just bear it in mind. Nothing stops you from keeping your traditional implementation parallel with the Webpack one. In that case I would still recommend commenting it out for the time of tinyMCE implementation.</p>
<p>All these steps will ensure that things we’ll be implementing from now on work, and the old implementation doesn’t function as a fallback.</p>
<h4 id="heading-step-1-if-you-want-to-use-jquery-via-webpack"><strong>Step 1. If you want to use jQuery via webpack</strong></h4>
<p>Adding jQuery through Webpack is as simple as running <code>yarn add jquery</code> and adding the following code to the <code>config/webpack/environment.js</code>:</p>
<pre><code><span class="hljs-keyword">const</span> { environment } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@rails/webpacker'</span>)<span class="hljs-keyword">const</span> webpack = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack'</span>)environment.plugins.prepend(<span class="hljs-string">'Provide'</span>,  <span class="hljs-keyword">new</span> webpack.ProvidePlugin({    <span class="hljs-attr">$</span>: <span class="hljs-string">'jquery'</span>,    <span class="hljs-attr">jQuery</span>: <span class="hljs-string">'jquery'</span>  }))<span class="hljs-built_in">module</span>.exports = environment
</code></pre><h4 id="heading-step-2-get-the-tinymce-package"><strong>Step 2. Get the tinyMCE package</strong></h4>
<p>That is also pretty straightforward: run <code>yarn add tinymce</code>.</p>
<p>Then create a new file where we’ll place our function. I ended up with <code>app/javascript/vendor/tinyMce.js</code> with the following content:</p>
<pre><code><span class="hljs-keyword">import</span> tinymce <span class="hljs-keyword">from</span> <span class="hljs-string">'tinymce/tinymce'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'tinymce/themes/modern/theme'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'tinymce/plugins/table'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'tinymce/plugins/lists'</span>;
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tinyMce</span>(<span class="hljs-params"></span>) </span>{    tinymce.init({        <span class="hljs-attr">selector</span>: <span class="hljs-string">'textarea.tinymce'</span>,
</code></pre><pre><code>        <span class="hljs-comment">// some other settings, like height, language,         // order of buttons on your toolbar etc.</span>
</code></pre><pre><code>        plugins: [            <span class="hljs-string">'table'</span>, <span class="hljs-string">'lists'</span>        ]    });}
</code></pre><pre><code><span class="hljs-comment">// if you're using a language file, you can place its content here</span>
</code></pre><pre><code><span class="hljs-keyword">export</span> { tinyMce };
</code></pre><h4 id="heading-step-3-import-everything-to-the-applicationjs"><strong>Step 3. Import everything to the <code>application.js</code></strong></h4>
<p>We can import our function like so:</p>
<p><code>import { tinyMce } from "../vendor/tinyMce";</code></p>
<p>and then call it:</p>
<pre><code><span class="hljs-built_in">document</span>.addEventListener(“turbolinks:load”, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{    tinyMce(); });
</code></pre><p>As you can see, we also replaced the jQuery code with ES6.</p>
<h4 id="heading-step-4-get-the-tinymce-skin-to-work"><strong>Step 4. Get the tinyMCE skin to work</strong></h4>
<p>If you run your <code>webpack-dev-server</code> and <code>rails s</code> you might be surprised to see that your text editor is not there. One look in the console and you’ll see the following error:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*fCntK4ZDJtVxvGobG4V0oA.png" alt="Image" width="710" height="53" loading="lazy"></p>
<p>This is because tinyMCE will not work without a skin, and pulling it in through Webpack requires its explicit import. We can do this by including this line in our <code>tinyMce.js</code> file, right after the other import statements. The path is relative to the <code>node_modules</code> folder:</p>
<pre><code><span class="hljs-keyword">import</span> ‘tinymce/skins/lightgray/skin.min.css’;
</code></pre><p><strong>At this point you should have your editor working.</strong></p>
<p>But… if you look into the console, you might be disappointed to see that you are still getting 2 errors:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uOpqUB3N2qAIzuDH1zRNOw.png" alt="Image" width="800" height="59" loading="lazy"></p>
<p>Don’t despair! There is an easy fix. Just add <code>skin: false</code> to your <code>function tinyMce()</code> config and it should do the trick. This will prevent the default files from loading.</p>
<p>Congrats! You just got your tinyMCE up and running!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to pass Rails instance variables into Vue components ]]>
                </title>
                <description>
                    <![CDATA[ By Gareth Fuller I’m currently working with a legacy Rails application. We are slowly transitioning the front-end from Rails views to a Vue application. As part of this transition, we have some elements that we want to turn into global Vue components... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-pass-rails-instance-variables-into-vue-components-7fed2a14babf/</link>
                <guid isPermaLink="false">66c353de91148fc1d02ee048</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 15 Mar 2018 09:54:26 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*5FJEL2CTeSHvTBsCJd0YFQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Gareth Fuller</p>
<p>I’m currently working with a legacy Rails application. We are slowly transitioning the front-end from Rails views to a Vue application.</p>
<p>As part of this transition, we have some elements that we want to turn into global Vue components. We want to be able to use these components within our existing Rails views and within a Vue application without having to customize each component to handle both situations.</p>
<p>Before I share my solution to this problem, here is an example single file Vue component that we want to be able to use in both scenarios (Rails view and Vue Application):</p>
<pre><code><span class="hljs-comment">// Payments.vue</span>
</code></pre><pre><code>&lt;template lang=<span class="hljs-string">"html"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"payments&gt;    &lt;div class="</span><span class="hljs-attr">payment</span>" <span class="hljs-attr">v-for</span>=<span class="hljs-string">"payment in payments&gt;      {{ payment.amount }}    &lt;/div&gt;  &lt;/div&gt;</span></span></span>&lt;/template&gt;
</code></pre><pre><code>&lt;script&gt;<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  <span class="hljs-attr">name</span>: <span class="hljs-string">'payments'</span>
</code></pre><pre><code>  props: {    <span class="hljs-attr">payments</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">Array</span> }  }}&lt;/script&gt;
</code></pre><pre><code>&lt;style lang=<span class="hljs-string">"scss"</span> scoped&gt;&lt;/style&gt;
</code></pre><p>From within a Vue app, this is a straightforward component to use, right? For example:</p>
<pre><code><span class="hljs-comment">// app/javascript/App.vue</span>
</code></pre><pre><code>&lt;template lang=<span class="hljs-string">"html"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app&gt;    &lt;payments :payments="</span><span class="hljs-attr">payments</span>" /&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>&lt;/template&gt;
</code></pre><pre><code>&lt;script&gt;<span class="hljs-keyword">import</span> Payments <span class="hljs-keyword">from</span> <span class="hljs-string">'./Payments.vue'</span>
</code></pre><pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  <span class="hljs-attr">name</span>: <span class="hljs-string">'app'</span>,
</code></pre><pre><code>  components: { Payments },
</code></pre><pre><code>  data () {    <span class="hljs-keyword">return</span> {      <span class="hljs-attr">payments</span>: [        { <span class="hljs-attr">amount</span>: <span class="hljs-number">123.00</span> },        { <span class="hljs-attr">amount</span>: <span class="hljs-number">124.00</span> }      ]    }  }&lt;/script&gt;
</code></pre><pre><code>&lt;style lang=<span class="hljs-string">"scss"</span> scoped&gt;&lt;/style&gt;
</code></pre><p>But what about using it in a Rails view?</p>
<h3 id="heading-solution">Solution</h3>
<p>So a solution for using the <em>Payments.vue</em> component in Rails looks like this:</p>
<pre><code><span class="hljs-comment">// app/views/payments/index.haml</span>
</code></pre><pre><code>.global-comp  = content_tag <span class="hljs-string">'comp-wrapper'</span>, nil, <span class="hljs-attr">data</span>: { <span class="hljs-attr">component</span>: <span class="hljs-string">'payments'</span>, <span class="hljs-attr">props</span>: { <span class="hljs-attr">payments</span>: @payments } }.to_json
</code></pre><p>Let’s break this element down.</p>
<p><code>.global-comp</code> is a div (with class “global-comp”) for mounting a super simple Vue instance. This Vue instance gives us a wrapper component to use called <em>CompWrapper.vue</em> (we’ll get to what CompWrapper is for in a minute).</p>
<p>Here is the Vue instance mounted to <code>.global-comp</code>:</p>
<pre><code><span class="hljs-comment">// app/javascript/packs/global_comp.js</span>
</code></pre><pre><code><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue/dist/vue.esm'</span><span class="hljs-keyword">import</span> CompWrapper <span class="hljs-keyword">from</span> <span class="hljs-string">'./CompWrapper'</span>
</code></pre><pre><code><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, <span class="hljs-function">() =&gt;</span> {  <span class="hljs-keyword">const</span> app = <span class="hljs-keyword">new</span> Vue({    <span class="hljs-attr">components</span>: { CompWrapper }  }).$mount(<span class="hljs-string">'.global-comp'</span>)})
</code></pre><p>All this does is make the component (<em>CompWrapper.vue</em>) available to us within a div with the class <code>global-comp</code>.</p>
<p>If you are using <a target="_blank" href="https://github.com/rails/webpacker">Webpacker</a> with Rails, you will need to include this pack within your layout somewhere before the closing body tag. For example:</p>
<pre><code><span class="hljs-comment">// app/views/layouts/application.haml</span>
</code></pre><pre><code>...
</code></pre><pre><code>= javascript_pack_tag <span class="hljs-string">"global_comp"</span>
</code></pre><h4 id="heading-compwrappervue">CompWrapper.vue</h4>
<p>This is the fun part. <em>CompWrapper.vue</em> allows us to pass:</p>
<ol>
<li>The name of the component we want to use, for example, “payments”</li>
<li>The props we want to pass to it</li>
</ol>
<p>The whole purpose of this wrapper component is to allow us to pass Rails instance variables like <code>@payments</code> into our components as props without having to handle this from within each component like <em>Payments.vue.</em></p>
<p>So here is <em>CompWrapper.vue</em>:</p>
<pre><code><span class="hljs-comment">// app/javascript/CompWrapper.vue</span>
</code></pre><pre><code>&lt;template lang=<span class="hljs-string">"html"</span>&gt;  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">component</span> <span class="hljs-attr">:is</span>=<span class="hljs-string">"data.component"</span> <span class="hljs-attr">v-bind</span>=<span class="hljs-string">"data.props"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">component</span>&gt;</span></span>&lt;/template&gt;
</code></pre><pre><code>&lt;script&gt;<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> components <span class="hljs-keyword">from</span> <span class="hljs-string">'./components'</span>
</code></pre><pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {  <span class="hljs-attr">name</span>: <span class="hljs-string">'comp-wrapper'</span>,
</code></pre><pre><code>  components,
</code></pre><pre><code>  data () {    <span class="hljs-keyword">return</span> {      <span class="hljs-attr">data</span>: {}    }  },
</code></pre><pre><code>  created() {    <span class="hljs-built_in">this</span>.data = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">this</span>.$attrs.data)  }}&lt;/script&gt;
</code></pre><pre><code>&lt;style lang=<span class="hljs-string">"scss"</span> scoped&gt;&lt;/style&gt;
</code></pre><p>The first thing the CompWrapper component is doing is taking the data attributes you set on the element in the Rails view, parsing the JSON, and setting an internal Vue data attribute with the parsed data:</p>
<pre><code>created() {  <span class="hljs-built_in">this</span>.data = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">this</span>.$attrs.data)}
</code></pre><p>with <code>this.data</code> set we can then use it to select the component we want to use and pass it the props we provided in our Rails view using a Vue dynamic component:</p>
<pre><code>&lt;component :is=<span class="hljs-string">"data.component"</span> v-bind=<span class="hljs-string">"data.props"</span>&gt;&lt;/component&gt;
</code></pre><p>And that’s it!</p>
<p>We can now use Vue components as they’re meant to be used, but from within our rails views. ?</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to optimize your queries to solve common scalability bottlenecks in Rails ]]>
                </title>
                <description>
                    <![CDATA[ By Usama Ashraf The (perfect) solution for the N+1 problem The n+1 query problem is one of the most common scalability bottlenecks. It involves fetching a list of resources from a database that includes other associated resources within them. This m... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/n-1-queries-batch-loading-active-model-serializers-in-rails-72662d7736f1/</link>
                <guid isPermaLink="false">66c35bd9c337fbd10a4b591e</guid>
                
                    <category>
                        <![CDATA[ Batch Loading ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 04 Mar 2018 19:18:58 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*Ph_m9KGrsfJPHGwpfXA8nQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Usama Ashraf</p>
<h4 id="heading-the-perfect-solution-for-the-n1-problem">The (perfect) solution for the N+1 problem</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Csu1xKKjVyRarXO3zKOQi-PwvPuR750NjwYt" alt="Image" width="800" height="343" loading="lazy"></p>
<p>The n+1 query problem is one of the most common scalability bottlenecks. It involves fetching a list of resources from a database that includes other associated resources within them. This means that we might have to query for the associated resources separately. So if you have a list of n parent objects, <em>another n queries will have to be executed for fetching the associated resources</em>. Let’s try to get rid of this O(n) conundrum.</p>
<p>If you’re comfortable with Rails, <a target="_blank" href="https://github.com/rails-api/active_model_serializers">Active Model Serializers</a>, and already have a good idea about what our problem is going to be, then maybe you can jump straight into the code <a target="_blank" href="https://gist.github.com/UsamaAshraf/95b0c8d0d64ee193148342a931c0a423">here</a>.</p>
<h4 id="heading-a-concrete-example">A Concrete Example</h4>
<p>Say you’re fetching an array of <strong>Post</strong> objects at a GET endpoint. You also want to load the respective authors of the posts, embedding an <strong>author</strong> object within each of the post objects. Here’s a naive way of doing it:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostsController</span> &lt; <span class="hljs-title">ApplicationController</span>    <span class="hljs-title">def</span> <span class="hljs-title">index</span>        <span class="hljs-title">posts</span> </span>= Post.all              render json: posts    endend
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Post</span>  <span class="hljs-title">belongs_to</span> :<span class="hljs-title">author</span>, <span class="hljs-title">class_name</span>: '<span class="hljs-title">User</span>'<span class="hljs-title">end</span></span>
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostSerializer</span> &lt; <span class="hljs-title">ActiveModel</span>::<span class="hljs-title">Serializer</span>    <span class="hljs-title">attributes</span> :<span class="hljs-title">id</span>, :<span class="hljs-title">title</span>, :<span class="hljs-title">details</span></span>
</code></pre><pre><code>  belongs_to :author end
</code></pre><p>For each of the n <strong>Post</strong> objects being rendered, a query will run to fetch the corresponding <strong>User</strong> object. Hence we’ll run a total of n+1 queries. This is disastrous. And here’s how you fix it by eager loading the <strong>User</strong> object:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostsController</span> &lt; <span class="hljs-title">ApplicationController</span>    <span class="hljs-title">def</span> <span class="hljs-title">index</span>        # <span class="hljs-title">Runs</span> <span class="hljs-title">a</span> <span class="hljs-title">SQL</span> <span class="hljs-title">join</span> <span class="hljs-title">with</span> <span class="hljs-title">the</span> <span class="hljs-title">users</span> <span class="hljs-title">table</span>.    <span class="hljs-title">posts</span> </span>= Post.includes(:author).all              render json: posts    endend
</code></pre><h4 id="heading-when-a-simple-join-is-not-possible">When A Simple Join Is Not Possible</h4>
<p>Until now there’s been absolutely nothing new for veterans.</p>
<p>But let’s complicate this. <em>Let’s assume that the site’s users are not being stored in the same RDMS as the posts are. Rather, the users are documents stored in MongoDB (for whatever reason).</em> How do we modify our <strong>Post</strong> serializer to fetch the user now, optimally? This would be going back to square one:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostSerializer</span> &lt; <span class="hljs-title">ActiveModel</span>::<span class="hljs-title">Serializer</span>    <span class="hljs-title">attributes</span> :<span class="hljs-title">id</span>, :<span class="hljs-title">title</span>, :<span class="hljs-title">details</span>, :<span class="hljs-title">author</span></span>
</code></pre><pre><code>  # Will run n Mongo queries <span class="hljs-keyword">for</span> n posts being rendered.  def author    User.find(object.author_id)  endend
</code></pre><pre><code># This is now a Mongoid <span class="hljs-built_in">document</span>, not an ActiveRecord model.class User    include Mongoid::Document    include Mongoid::Timestamps    # ...end
</code></pre><p>The predicament that our users now reside in a Mongo database can be substituted with, say, calling a 3rd party HTTP service for fetching the users or storing them in a completely different RDMS. <em>Our essential problem remains that there’s no way to ‘join’ the users datastore with the posts table and get the response we want in a single query.</em></p>
<p>Of course, we can do better. We can fetch the entire response in two queries:</p>
<ul>
<li>Fetch all the posts without the <strong>author</strong> attribute (1 SQL query).</li>
<li>Fetch all the corresponding authors by running a where-in query with the user IDs plucked from the array of posts (1 Mongo query with an IN clause).</li>
</ul>
<pre><code>posts      = Post.allauthor_ids = posts.pluck(:author_id)authors    = User.where(:_id.in =&gt; author_ids)
</code></pre><pre><code># Somehow pass the author objects to the post serializer and# map them to the correct post objects. Can<span class="hljs-string">'t imagine what # exactly that would look like, but probably not pretty.render json: posts, pass_some_parameter_maybe: authors</span>
</code></pre><h4 id="heading-enter-batch-loader">Enter Batch Loader</h4>
<p>So our original optimization problem has been reduced to “how do we make this code readable and maintainable”. The folks at <a target="_blank" href="https://www.universe.com/about">Universe</a> have come up with an absolute gem (too obvious?). <a target="_blank" href="https://github.com/exAspArk/batch-loader">Batch Loader</a> has been incredibly helpful to me recently.</p>
<p><code>gem 'batch-loader'</code></p>
<p><code>bundle install</code></p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostSerializer</span> &lt; <span class="hljs-title">ActiveModel</span>::<span class="hljs-title">Serializer</span>    <span class="hljs-title">attributes</span> :<span class="hljs-title">id</span>, :<span class="hljs-title">title</span>, :<span class="hljs-title">details</span>, :<span class="hljs-title">author</span></span>
</code></pre><pre><code>  def author    object.get_author_lazily  endend
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Post</span>  <span class="hljs-title">def</span> <span class="hljs-title">get_author_lazily</span>    # <span class="hljs-title">The</span> <span class="hljs-title">current</span> <span class="hljs-title">post</span> <span class="hljs-title">object</span> <span class="hljs-title">is</span> <span class="hljs-title">added</span> <span class="hljs-title">to</span> <span class="hljs-title">the</span> <span class="hljs-title">batch</span> <span class="hljs-title">here</span>,    # <span class="hljs-title">which</span> <span class="hljs-title">is</span> <span class="hljs-title">eventually</span> <span class="hljs-title">processed</span> <span class="hljs-title">when</span> <span class="hljs-title">the</span> <span class="hljs-title">block</span> <span class="hljs-title">executes</span>.       <span class="hljs-title">BatchLoader</span>.<span class="hljs-title">for</span>(<span class="hljs-title">self</span>).<span class="hljs-title">batch</span> <span class="hljs-title">do</span> |<span class="hljs-title">posts</span>, <span class="hljs-title">batch_loader</span>|</span>
</code></pre><pre><code>      author_ids = posts.pluck(:author_id)        User.where(:_id.in =&gt; author_ids).each <span class="hljs-keyword">do</span> |user|        post = posts.detect { |p| p.author_id == user._id.to_s }        #<span class="hljs-string">'Assign'</span> the user object to the right post.        batch_loader.call(post, user)            end        end    endend
</code></pre><p>If you’re familiar with JavaScript Promises, think of the <code>get_author_lazily</code> method as returning a Promise which is evaluated later. That’s a decent analogy, I think since <code>BatchLoader</code> uses <a target="_blank" href="https://ruby-doc.org/core-2.4.1/Enumerable.html#method-i-lazy">lazy Ruby objects</a>. By default, <code>BatchLoader</code> caches the loaded values, and so to keep the responses up-to-date you should add this to your <code>config/application.rb</code>:</p>
<pre><code>config.middleware.use BatchLoader::Middleware
</code></pre><p>That’s it! We’ve solved an advanced version of the n+1 queries problem while keeping our code clean and using Active Model Serializers the right way.</p>
<h4 id="heading-using-ams-for-nested-resources">Using AMS for Nested Resources</h4>
<p>One problem though. If you have a <strong>User</strong> serializer (Active Model Serializers work with Mongoid as well), that <em>won’t</em> be called for the lazily loaded <strong>author</strong> objects, unlike before. To fix this, we can use a Ruby block and serialize the <strong>author</strong> objects before they’re ‘assigned’ to the posts.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PostSerializer</span> &lt; <span class="hljs-title">ActiveModel</span>::<span class="hljs-title">Serializer</span>    <span class="hljs-title">attributes</span> :<span class="hljs-title">id</span>, :<span class="hljs-title">title</span>, :<span class="hljs-title">details</span>, :<span class="hljs-title">author</span></span>
</code></pre><pre><code>  def author    object.get_author_lazily <span class="hljs-keyword">do</span> |author|      # Serialize the author after it has been loaded.           ActiveModelSerializers::SerializableResource                             .new(author)                             .as_json[:user]    end  endend
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Post</span>  <span class="hljs-title">def</span> <span class="hljs-title">get_author_lazily</span>    # <span class="hljs-title">The</span> <span class="hljs-title">current</span> <span class="hljs-title">post</span> <span class="hljs-title">object</span> <span class="hljs-title">is</span> <span class="hljs-title">added</span> <span class="hljs-title">to</span> <span class="hljs-title">the</span> <span class="hljs-title">batch</span> <span class="hljs-title">here</span>,    # <span class="hljs-title">which</span> <span class="hljs-title">is</span> <span class="hljs-title">eventually</span> <span class="hljs-title">processed</span> <span class="hljs-title">when</span> <span class="hljs-title">the</span> <span class="hljs-title">block</span> <span class="hljs-title">executes</span>.       <span class="hljs-title">BatchLoader</span>.<span class="hljs-title">for</span>(<span class="hljs-title">self</span>).<span class="hljs-title">batch</span> <span class="hljs-title">do</span> |<span class="hljs-title">posts</span>, <span class="hljs-title">batch_loader</span>|</span>
</code></pre><pre><code>      author_ids = posts.pluck(:author_id)      User.where(:_id.in =&gt; author_ids).each <span class="hljs-keyword">do</span> |user|        modified_user = block_given? ? <span class="hljs-keyword">yield</span>(user) : user        post = posts.detect { |p| p.author_id == user._id.to_s }          # <span class="hljs-string">'Assign'</span> the user object to the right post.        batch_loader.call(post, modified_user)            end        end    endend
</code></pre><p><a target="_blank" href="https://gist.github.com/UsamaAshraf/95b0c8d0d64ee193148342a931c0a423">Here’s</a> the entire code. Enjoy!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Rails Authorization with Pundit ]]>
                </title>
                <description>
                    <![CDATA[ By Joseph Gefroh Pundit is a Ruby gem that handles authorization via a very simple API. Remember that authorization is different from authentication — authentication is verifying that you are who you say you are, and authorization is verifying that y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/rails-authorization-with-pundit-a3d1afcb8fd2/</link>
                <guid isPermaLink="false">66c35d43ee410eea7c0987e8</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby on Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 25 Dec 2016 22:41:33 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9cb6e0740569d1a4cae0a6.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Joseph Gefroh</p>
<p><a target="_blank" href="https://github.com/elabs/pundit">Pundit</a> is a Ruby gem that handles authorization via a very simple API.</p>
<p>Remember that authorization is different from authentication — authentication is verifying that you are who you say you are, and authorization is verifying that you have permission to perform an action.</p>
<p>Pundit is squarely within the authorization camp — use another authentication system like <a target="_blank" href="https://github.com/plataformatec/devise">Devise</a> to handle authentication.</p>
<h3 id="heading-how-you-work-with-pundit">How you work with Pundit</h3>
<p><strong>Step 1:</strong> You create a <code>Policy</code> class that deals with authorizing access to a specific type of record — whether it be a <code>Blog</code> or <code>Potato</code> or <code>User</code>.</p>
<p><strong>Step 2:</strong> You call the built-in <code>authorize</code> function, passing in what you’re trying to authorize access to.</p>
<p><strong>Step 3:</strong> Pundit will find the appropriate <code>Policy</code> class and call the <code>Policy</code> method that matches the name of the method you are authorizing. If it returns true, you have permission to perform the action. If not, it’ll throw an exception.</p>
<p>It’s pretty straightforward. Logic for specific models is encapsulated into its own policy class, which is great for keeping things tidy. Competing authorization library <a target="_blank" href="https://github.com/CanCanCommunity/cancancan">cancancan</a> had issues with complicated permissions getting out of hand.</p>
<h3 id="heading-minor-tweaks-required">Minor tweaks required</h3>
<p>Pundit’s simple conventions sometimes need to be tweaked to support more complex authorization use cases.</p>
<h4 id="heading-access-more-information-from-within-a-policy">Access more information from within a Policy</h4>
<p>By default, Pundit provides two objects to your authorization context: the <code>User</code> and the <code>Record</code> being authorized. This is sufficient if you have system-wide roles in your system like <code>Admin</code> or <code>Moderator</code>, but isn’t enough when you need authorize to a more specific context.</p>
<p>Let’s say you had a system that supported the concept of an <code>Organization</code>, and you had to support different roles within those organizations. System-wide authorization won’t cut it — you don’t want an admin of Organization Potato to be able to do things to Organization Orange unless they are an admin of both organizations. When authorizing this case, you would need access to 3 items: the <code>User</code>, the <code>Record</code>, and the user’s role information in the <code>Organization</code>. The ideal case would be to have access to the organization the record belongs to, but let’s make it harder and say we don’t have access to that via the record or the user.</p>
<p>Pundit provides an opportunity to provide additional context. By defining a function called <code>pundit_user</code>, this allows you to change what is considered a <code>user</code>. If you return a object with the authorization context from that function, that context will be available to your policies.</p>
<p><code>application_controller.rb</code></p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ApplicationController</span> &lt; <span class="hljs-title">ActionController</span>::<span class="hljs-title">Base</span>  <span class="hljs-title">include</span> <span class="hljs-title">Pundit</span></span>
</code></pre><pre><code>  def pundit_user    AuthorizationContext.new(current_user, current_organization)  endend
</code></pre><p><code>authorization_context.rb</code></p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AuthorizationContext</span>  <span class="hljs-title">attr_reader</span> :<span class="hljs-title">user</span>, :<span class="hljs-title">organization</span></span>
</code></pre><pre><code>  def initialize(user, organization)    @user = user    @organization = organization  endend
</code></pre><p><code>application_policy.rb</code></p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ApplicationPolicy</span>  <span class="hljs-title">attr_reader</span> :<span class="hljs-title">request_organization</span>, :<span class="hljs-title">user</span>, :<span class="hljs-title">record</span></span>
</code></pre><pre><code>  def initialize(authorization_context, record)    @user = authorization_context.user    @organization = authorization_context.organization    @record = record  end
</code></pre><pre><code>  def index?    # Your policy has access to @user, @organization, and @record.    endend
</code></pre><p>Your policies would now have access to all three kinds of information — you should be able to see how you would access more information if you needed it.</p>
<h4 id="heading-override-convention-and-specify-which-policy-to-use">Override convention and specify which Policy to use</h4>
<p>Pundit uses naming conventions to match up what you’re trying to authorize with the right policy. Most of the time this works well, but in certain cases you may need to override this convention, such as when you want to authorize a general dashboard action that doesn’t have an associated model. You can pass in symbols to specify which action or policy to use for authorization:</p>
<pre><code>#Below will call DashboardPolicy#bake_potato?authorize(:dashboard, :bake_potato?)
</code></pre><p>If you have a model that is named differently, you can also override the <code>policy_class</code> function within the model itself:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DashboardForAdmins</span>  <span class="hljs-title">def</span> <span class="hljs-title">self</span>.<span class="hljs-title">policy_class</span>   <span class="hljs-title">DashboardPolicy</span>     # <span class="hljs-title">This</span> <span class="hljs-title">forces</span> <span class="hljs-title">Pundit</span> <span class="hljs-title">to</span> <span class="hljs-title">use</span> <span class="hljs-title">Dashboard</span> <span class="hljs-title">Policy</span> <span class="hljs-title">instead</span> <span class="hljs-title">of</span> <span class="hljs-title">looking</span>    # <span class="hljs-title">for</span> <span class="hljs-title">DashboardForAdminsPolicy</span>  <span class="hljs-title">endend</span></span>
</code></pre><h3 id="heading-testing">Testing</h3>
<p>Authorization is one of those things I strong recommend having an automated test suite around. Setting them up incorrectly can be catastrophic, and it’s in my opinion one of the most tedious things to test manually. Being able to run a single command and knowing that you haven’t inadvertently changed any authorization business rules is a great feeling.</p>
<p>Pundit makes testing authorization very simple.</p>
<pre><code>def test_user_cant_destroy?  assert_raises Pundit::NotAuthorizedError <span class="hljs-keyword">do</span>    authorize @record, :destroy?  endend
</code></pre><pre><code>def test_user_can_show?  authorize @record, :show?end
</code></pre><p>Overall I like Pundit. I’ve only been using it for a short while, but I already prefer it over cancancan — it just feels more maintainable and testable.</p>
<p>Did you find this story helpful? Please <strong>Clap</strong> to show your support!<br>If you didn’t find it helpful, please let me know why with a <strong>Comment</strong>!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Best Gitter channels on: Ruby ]]>
                </title>
                <description>
                    <![CDATA[ By Gitter Ruby is a general purpose programming language created in the 1990s by Yukihiro “Matz” Matsumoto. It’s also considered one of the best languages to start with when you’re first learning to code. We have lots of channels dedicated to Ruby-re... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/best-gitter-channels-on-ruby-87ec12ead3d3/</link>
                <guid isPermaLink="false">66c345a942d4db64acf4cbed</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby on Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 16 Jun 2016 10:30:37 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*A3zm9h0v8CDvAGRXlozJkQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Gitter</p>
<p>Ruby is a general purpose programming language created in the 1990s by Yukihiro “Matz” Matsumoto. It’s also considered one of the best languages to start with when you’re first learning to code. We have lots of channels dedicated to Ruby-related projects on Gitter, both for advanced developers and beginners. Check them out!</p>
<ul>
<li><a target="_blank" href="https://gitter.im/rails/rails?utm_source=blog&amp;utm_medium=content&amp;utm_campaign=ruby"><strong>rails/rails</strong></a> — General chat around Ruby on Rails. <a target="_blank" href="http://rubyonrails.org/">http://rubyonrails.org</a></li>
<li><a target="_blank" href="https://gitter.im/voltrb/volt?utm_medium=content&amp;utm_campaign=ruby"><strong>voltrb/volt</strong></a> — Volt is a reactive web framework where your Ruby runs on both server and client.</li>
<li><a target="_blank" href="https://gitter.im/opal/opal?utm_medium=content&amp;utm_campaign=ruby"><strong>opal/opal</strong></a> — Opal is a Ruby to Javascript compiler. It is source-to-source, making it fast as a runtime. Opal includes a compiler (which can be run in any browser), a corelib and runtime implementation.</li>
<li><a target="_blank" href="https://gitter.im/hanami/chat"><strong>hanami/chat</strong></a> <strong>—</strong> <a target="_blank" href="http://hanamirb.org/">Hanami</a> is a modern web framework for Ruby.</li>
<li><a target="_blank" href="https://gitter.im/jekyll/jekyll?utm_medium=content&amp;utm_campaign=ruby"><strong>jekyll/jekyll</strong></a> — Jekyll is a blog-aware, static site generator in Ruby.</li>
<li><a target="_blank" href="https://gitter.im/aws/aws-sdk-ruby?utm_medium=content&amp;utm_campaign=ruby"><strong>aws/aws-sdk-ruby</strong></a> — The official AWS SDK for Ruby.</li>
<li><a target="_blank" href="https://gitter.im/refinery/refinerycms?utm_medium=content&amp;utm_campaign=ruby"><strong>refinery/refinerycms</strong></a> — Refinery CMS is an extendable Ruby on Rails CMS that supports Rails 4.2.</li>
<li><a target="_blank" href="https://gitter.im/rubinius/rubinius?utm_medium=content&amp;utm_campaign=ruby"><strong>rubinius/rubinius</strong></a> — Rubinius is a modern language platform that supports a number of programming languages. Rubinius includes a bytecode virtual machine, generational garbage collector, and just-in-time (JIT) native machine code compiler. Rubinius provides concurrency support via native OS threads with no global interpreter lock.</li>
<li><a target="_blank" href="https://gitter.im/dev-ua/ruby-ua?utm_medium=content&amp;utm_campaign=ruby"><strong>dev-ua/ruby-ua</strong></a> — Ukrainian developers chat dedicated to Ruby.</li>
<li><a target="_blank" href="https://gitter.im/bbatsov/rubocop?utm_medium=content&amp;utm_campaign=ruby"><strong>bbatsov/rubocop</strong></a> — Rubocop is a robust static Ruby code analyzer, based on the community Ruby style guide.</li>
<li><a target="_blank" href="https://gitter.im/puma/puma?utm_medium=content&amp;utm_campaign=ruby"><strong>puma/puma</strong></a> <em>—</em> Puma is a ruby web server built for concurrency.</li>
<li><a target="_blank" href="https://gitter.im/cucumber/cucumber-ruby?utm_medium=content&amp;utm_campaign=ruby"><strong>cucumber/cucumber-ruby</strong></a> <em>—</em> Cucumber is a tool for running automated tests written in plain language.</li>
<li><a target="_blank" href="https://gitter.im/mruby/mruby?utm_medium=content&amp;utm_campaign=ruby"><strong>mruby/mruby</strong></a> — mruby is the lightweight implementation of the Ruby language complying to (part of) the <a target="_blank" href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579">ISO standard</a>. Its syntax is Ruby 1.9 compatible.</li>
<li><a target="_blank" href="https://gitter.im/mperham/sidekiq?utm_medium=content&amp;utm_campaign=ruby"><strong>mperham/sidekiq</strong></a> <strong>—</strong> Sidekiq is simple, efficient background processing for Ruby.</li>
<li><a target="_blank" href="https://gitter.im/rebelidealist/stripe-ruby-mock?utm_medium=content&amp;utm_campaign=ruby"><strong>rebelidealist/stripe-ruby-mock</strong></a> <strong>—</strong> A mocking library for testing stripe ruby.</li>
<li><a target="_blank" href="https://gitter.im/trailblazer/chat"><strong>trailblazer/chat</strong></a> <strong>—</strong> <a target="_blank" href="http://trailblazer.to/">Trailblazer</a> gives you a high-level architecture for web applications.</li>
<li><a target="_blank" href="https://gitter.im/dry-rb/chat"><strong>dry-rb/chat</strong></a> <strong>—</strong> dry-rb is a collection of next-generation Ruby libraries, each intended to encapsulate a common task.</li>
</ul>
<p>Looking for something else? Check out our <a target="_blank" href="https://gitter.im/explore/tags/javascript,php,ruby">Explore</a> section or easily <a target="_blank" href="https://gitter.im/home#createroom">start your own channel here.</a></p>
<p>Did we miss an channel that you think should be featured? Drop us a line in the <a target="_blank" href="https://gitter.im/gitterHQ/gitter">Gitter HQ</a> and we will add it to the list.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
