<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Robert Hustead</title>
    <description>The latest articles on DEV Community by Robert Hustead (@husteadrobert).</description>
    <link>https://dev.to/husteadrobert</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F87838%2F43b3c721-4ae7-4cb3-aeb3-aa100ad7961f.jpg</url>
      <title>DEV Community: Robert Hustead</title>
      <link>https://dev.to/husteadrobert</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/husteadrobert"/>
    <language>en</language>
    <item>
      <title>How to use a non-mac mouse to move between spaces and open Mission Control on MacOS</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Wed, 22 Oct 2025 03:57:01 +0000</pubDate>
      <link>https://dev.to/husteadrobert/how-to-use-a-non-mac-mouse-to-move-between-spaces-and-open-mission-control-on-macos-3pe7</link>
      <guid>https://dev.to/husteadrobert/how-to-use-a-non-mac-mouse-to-move-between-spaces-and-open-mission-control-on-macos-3pe7</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR Just follow these steps, full explanation will follow.
&lt;/h1&gt;

&lt;p&gt;1) Download and install &lt;a href="https://github.com/MacGesture/MacGesture" rel="noopener noreferrer"&gt;"MacGesture"&lt;/a&gt; using homebrew with &lt;br&gt;
&lt;code&gt;brew install --cask macgesture&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2) In "Preferences", navigate to the AppleScript tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhdp7tm17qajymahi4kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhdp7tm17qajymahi4kq.png" alt="AppleScript example image" width="660" height="545"&gt;&lt;/a&gt;&lt;br&gt;
3) Click the "+" button to create 3 new AppleScripts, giving them the following names and scripts:&lt;br&gt;
a) Navigate Left: &lt;code&gt;tell application "System Events" to key code 123 using control down&lt;/code&gt;&lt;br&gt;
b) Navigate Right: &lt;code&gt;tell application "System Events" to key code 124 using control down&lt;/code&gt;&lt;br&gt;
c) Open Mission Control: &lt;code&gt;tell application "System Events" to key code 126 using control down&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4) Navigate to the "Gestures" tab, and delete any gestures that might exist.  Add 3 new Gestures, selecting "Add a AppleScript Rule" when prompted by clicking the "+" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2uuqz6ahei5phz6686s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2uuqz6ahei5phz6686s.png" alt="Gesture example image" width="660" height="570"&gt;&lt;/a&gt;&lt;br&gt;
5) Give these new Gestures the following properties.  Yes, I really do mean give Gesture Left the Navigate Right action, etc.&lt;br&gt;
a) Gesture: &lt;code&gt;L&lt;/code&gt;, Filter &lt;code&gt;*&lt;/code&gt;, Action: &lt;code&gt;Navigate Right&lt;/code&gt;, Note: [Whatever you want, not necessary], Lightening Bolt: [Unchecked]&lt;br&gt;
b) Gesture: &lt;code&gt;R&lt;/code&gt;, Filter &lt;code&gt;*&lt;/code&gt;, Action: &lt;code&gt;Navigate Left&lt;/code&gt;, Note: [Whatever you want, not necessary], Lightening Bolt: [Unchecked]&lt;br&gt;
c) Gesture: &lt;code&gt;U&lt;/code&gt;, Filter &lt;code&gt;*&lt;/code&gt;, Action: &lt;code&gt;Open Mission Control&lt;/code&gt;, Note: [Whatever you want, not necessary], Lightening Bolt: [Unchecked]&lt;/p&gt;

&lt;p&gt;6) Adjust any other General settings you want.&lt;/p&gt;

&lt;p&gt;Finished.  You can now hold down the right mouse button, flick the mouse to the left, and it will slide your current Screen to the right.  Same with the opposite.  Holding right mouse button and flicking up will open Mission Control.  Have fun!&lt;/p&gt;




&lt;h2&gt;
  
  
  Fuller Explanation that I expect no one to read
&lt;/h2&gt;

&lt;p&gt;I have a Mac I use for work, and while I love all the 'gestures' you can do with the track pad, mine recently blew up and I needed to go back to my boring windows style mouse.  However, I really like being able to scroll between different Desktops (called Spaces I guess?).  I want to keep that functionality, but I wanted to be able to do it with my mouse and not a track pad.&lt;/p&gt;

&lt;p&gt;I found the app mentioned above, and I tried making a custom gesture to be able to hold down the right mouse button, and flick the screen to the left or right.  I knew you could hold down CONTROL and press RIGHT or LEFT on the keyboard and it would switch Spaces, so I wanted to do the same but have my mouse's right button be CONTROL, and then it's movement be the LEFT or RIGHT. My problem was, whenever I tried to key in the macro for MacGesture, it wouldn't register CONTROL as part of the macro.&lt;/p&gt;

&lt;p&gt;AppleScript to the rescue!  Now, I set the custom macro to be a LEFT or RIGHT (or UP) movement while also holding down the CONTROL key, and I map them to basic Gesture "L" for left and "R" for right, setting them to run during any and all applications (the "*" in Filter)&lt;/p&gt;

&lt;p&gt;This took me longer than I want to admit to figure out, and every other explanation I found online has huge wordy explanations or a long Youtube video that no one wants to watch.  So hopefully this quick tutorial helps you out and you can get back to coding.  Good luck!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What to do when "Service page is currently unavailable." on AWS Console</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Thu, 02 Jan 2020 01:03:02 +0000</pubDate>
      <link>https://dev.to/husteadrobert/what-to-do-when-service-page-is-currently-unavailable-on-aws-console-4c2h</link>
      <guid>https://dev.to/husteadrobert/what-to-do-when-service-page-is-currently-unavailable-on-aws-console-4c2h</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take a chill pill and wait for a few minutes(hours).  It's likely just a bug on Amazon's end.  I'm writing this because I couldn't find any other mention of this page when I googled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While going through &lt;a href="https://serverless-stack.com/" rel="noopener noreferrer"&gt;this tutorial to create a serverless stack architecture on AWS&lt;/a&gt;, I was required to create a Federated Identity through Cognito using the AWS Console GUI on us-east-1.&lt;/p&gt;

&lt;p&gt;Having created the Federated Identity, I attempted to access it's Dashboard through the AWS Console but was greeted by a strange error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2xn7zwddqb0qxr92ft9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2xn7zwddqb0qxr92ft9w.png" alt="AWS Error Message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it comes to AWS services not working as intended, 99% of the time it's a User error problem, but this error message was a bit different than normal.  I had a Federated Identify on another account on another Region, and I was able to access that one just fine.  Something seemed wrong with us-east-1.&lt;/p&gt;

&lt;p&gt;I tried changing regions, and then going back to us-east-1 and accessing the Federated Identity Dashboard, and sometimes I was able to access it.  But whenever I tried to edit settings, it would kick me back to the above 500 error page.&lt;/p&gt;

&lt;p&gt;I tried googling for this specific error, but I couldn't find either 1) a fix or 2) any mention of this specific error page.&lt;/p&gt;

&lt;p&gt;It turned out that it just took some time (about an hour for me), but then I was able to access the page as normal.  However, diagnosing problems on AWS can be hugely difficult for those like me who are not well versed in it, and that difficulty is compounded when the problem isn't even on your end.  So, I felt I should leave some sort of record for the next poor engineer who goes searching for this specific error.&lt;/p&gt;

&lt;p&gt;(Of course, this is assuming you DIDN'T have any issues with the settings/code you have written.  As always, you should do a sanity check of your services and settings.)&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>infra</category>
      <category>devops</category>
      <category>panic</category>
    </item>
    <item>
      <title>How to use Global Navigation Guards with Nuxt Middleware, and why you absolutely should NOT</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Fri, 09 Aug 2019 10:40:26 +0000</pubDate>
      <link>https://dev.to/husteadrobert/how-to-use-global-navigation-guards-with-nuxt-middleware-and-why-you-absolutely-should-not-7bl</link>
      <guid>https://dev.to/husteadrobert/how-to-use-global-navigation-guards-with-nuxt-middleware-and-why-you-absolutely-should-not-7bl</guid>
      <description>&lt;p&gt;TLDR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's possible to use Global Navigation Guards with Nuxt by using Middleware&lt;/li&gt;
&lt;li&gt;In the Middleware, you have access to the context, by which you can directly access the Vue Router.&lt;/li&gt;
&lt;li&gt;By adding a Global Navigation Guard, that code will run every time your router is used, leading to unintended consequences&lt;/li&gt;
&lt;li&gt;Instead, use in-component Navigation Guards within your pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm still very new to Vue and Nuxt, but as we are using it at my job I'm trying to pick it up as I go.  We are building a task management system similar to Pivotal Tracker or Trello.  We have Lists, and within these Lists we have Tasks, and one Task showing its TaskDetails.  By clicking on the Tasks in the List you can change which TaskDetail is shown. I was faced with what I initially thought was an easy task.&lt;/p&gt;

&lt;p&gt;TASK: When a user is editing a text box within the TaskDetail, ensure the user does not accidently navigate away from the page (and losing their edit) by adding a confirm popup.&lt;/p&gt;

&lt;p&gt;Enter Navigation Guards (&lt;a href="https://router.vuejs.org/guide/advanced/navigation-guards.html" rel="noopener noreferrer"&gt;Navigation Guards | Vue Router&lt;/a&gt;) , which are "primarily used to guard navigations either by redirecting it or canceling it."  By using a Global Navigation Guard, I could ensure that anytime the Vue Router changes the route (when someone clicks on a different Task), I could check if they are editing a text box and then use a confirm popup.&lt;/p&gt;

&lt;p&gt;Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const router = new VueRouter({ ... })

router.beforeEach((to, from, next) =&amp;gt; {
  if(confirm("Are you sure?")) {
    next()
  } else {
    next(false)
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem: We are using Nuxt, which sets up the Vue-router automatically based on your file structure.  But there must be a way to use a Global Navigation Guard with Nuxt, right?&lt;/p&gt;

&lt;p&gt;I googled, and all I could find addressing this was &lt;a href="https://stackoverflow.com/questions/53322525/how-to-set-beforeresolve-navigation-guard-in-nuxt-js" rel="noopener noreferrer"&gt;one lone Stack Overflow question&lt;/a&gt;, which had no answer but at least a useful comment about how middleware was designed for exactly that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is middleware in Nuxt?
&lt;/h2&gt;

&lt;p&gt;"Middleware lets you define custom functions that can be run before rendering either a page or a group of pages." (&lt;a href="https://nuxtjs.org/guide/routing#middleware" rel="noopener noreferrer"&gt;Routing - Nuxt.js&lt;/a&gt;)  Also importantly, the Middleware has access to the Context (&lt;a href="https://nuxtjs.org/api/context" rel="noopener noreferrer"&gt;API: The Context - Nuxt.js&lt;/a&gt;), which has access to the store, which has access to the Vue Router!&lt;/p&gt;

&lt;p&gt;So my idea is now simple: create a middleware that accesses the router directly, add a Global Navigation Guard so that whenever the router changes pages it confirms with the user if they really want to move.  Let's do it!&lt;/p&gt;

&lt;p&gt;For my middleware I created this basic file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;in check-before-move.js

export default function ({ store }) {
  store.app.router.beforeEach((to, from, next) =&amp;gt; {
    if(confirm("Are you sure?")) {
      next()
    } else {
      next(false)
    }
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then added that to the config for nuxt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;in nuxt.config.js

  router: {
    middleware: "check-before-move"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lead to a sticky little problem.  Can you spot it?  If my middleware really does run every time the router runs, what is going to happen?&lt;/p&gt;

&lt;p&gt;That's right, every time the router runs I'm adding ANOTHER Global Navigation Guard.  My user has to confirm once, then twice, then three times..etc every time they navigate to different Tasks.  Remember, that middleware file is running from start to finish every time the router moves.  And each time that middleware file runs, we are doing another &lt;code&gt;beforeEach&lt;/code&gt;.  It's obvious looking at it now, but it took me a long time to figure out at the time!&lt;/p&gt;

&lt;p&gt;So my dumb brain said, "Oh ok I just need to add a check to see if I've set it up already", and I immediately changed my code to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;in check-before-move.js

export default function ({ store }) {
  let setup = false
  if(!setup) {
    store.app.router.beforeEach((to, from, next) =&amp;gt; {
      setup = true
      if(confirm("Are you sure?")) {
        next()
      } else {
        next(false)
      }
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That, as you can imagine, also did not work (read above where I said the code runs from start to finish every time and you'll see why my master plan failed)&lt;/p&gt;

&lt;p&gt;So as we can see, YES you can add a Global Navigation Guard in Nuxt by using Middleware, but NO you should not do it(or at least be very sure about what you're doing before implementing it).&lt;/p&gt;

&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;For anyone else who may be trying to figure out how to implement the same feature in their own project and is suffering like I did, I'll tell you how I managed to implement a solution.  Instead of going global, I introduced an In-component Guard.  Be careful though, those In-component Guards only work on PAGES, not components (even though Pages are Components but Nuxt has opinions on these matters), so look into In-component Guards here (&lt;a href="https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards" rel="noopener noreferrer"&gt;Navigation Guards | Vue Router&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

&lt;p&gt;(Note: I am new to Vue/Nuxt as I stated before, so if you spot any mistakes, feel free to point them out!)&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>beginners</category>
      <category>bug</category>
    </item>
    <item>
      <title>Loading and Authorizing ActsAsTaggable tags using the Cancan authorization library</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Sat, 27 Oct 2018 12:56:05 +0000</pubDate>
      <link>https://dev.to/husteadrobert/loading-and-authorizing-actsastaggable-tags-using-the-cancan-authorization-library-bfn</link>
      <guid>https://dev.to/husteadrobert/loading-and-authorizing-actsastaggable-tags-using-the-cancan-authorization-library-bfn</guid>
      <description>&lt;p&gt;tl;dr (Too long, didn’t read)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SomeController &amp;lt; ApplicationController
  load_and_authorize_resource class: ActsAsTaggableOn::Tag

  def index; end  #@tags is available in this action
  def show; end #@tag is available in this action
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;The Cancan library is very useful for controlling resources and what users are allowed to read, write, modify, or change them. Normally, when load_and_authorize_resource is included into a RESTful style Controller, it uses a before filter to load an instance variable into memory. However, things can get difficult if you want to load a resource from another class or if the model you wish to use is namespaced differently from the controller.&lt;/p&gt;

&lt;p&gt;If you’re using ActsAsTaggableOn to add tags to some models in your app, you can still load those tags as a resource using the code above. From the Cancan documentation on github (&lt;a href="https://github.com/ryanb/cancan/wiki/authorizing-controller-actions#custom-class" rel="noopener noreferrer"&gt;https://github.com/ryanb/cancan/wiki/authorizing-controller-actions#custom-class&lt;/a&gt;)&lt;br&gt;
“If the model class is namespaced differently than the controller you will need to specify the :class option.”&lt;/p&gt;

&lt;p&gt;Remember to set your user abilities for accessing Tags in your abilities files when using Cancan!&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>cancan</category>
      <category>rails</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to stop API calls in RSpec and Return your Own Data</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Sat, 27 Oct 2018 12:53:03 +0000</pubDate>
      <link>https://dev.to/husteadrobert/how-to-stop-api-calls-in-rspec-and-return-your-own-data-4fa2</link>
      <guid>https://dev.to/husteadrobert/how-to-stop-api-calls-in-rspec-and-return-your-own-data-4fa2</guid>
      <description>&lt;p&gt;tl;dr You can explicitly return whatever data you want from external API requests using Webmock and stubbing requests.&lt;/p&gt;

&lt;p&gt;How do you test a Controller that makes an API request to another website, but you want to control what exactly is returned? For example, you want to test a Controller that queries Twitter for tweets, but you don’t want to be at the mercy of whatever tweets are being created that second because you want to test how well you can scrape certain keywords.&lt;/p&gt;

&lt;p&gt;That’s where Webmock comes in. &lt;a href="https://github.com/bblimke/webmock" rel="noopener noreferrer"&gt;https://github.com/bblimke/webmock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By adding the code below to your spec_helper or rails_helper file, you can stub external API requests and control the data that is returned to your controllers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.before(:each) do
 stub_request(:get, /some.website.api/).
 with(headers: {‘Accept’: ‘*/*’, ‘User-Agent’: ‘Ruby’ }).
 to_return(status: 200, body:’{“test”: 0}’, headers: {})
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets go through each line:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config.before(:each)&lt;/code&gt; do This tells RSpec to run the following code before each spec.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stub_request(:get, /some.website.api/).&lt;/code&gt; This is the first part of the stub_request method we get from Webmock. It specifies the type of request (:get -&amp;gt; GET), but you can also use any other RESTful request, including the symbol :any to stub any request that comes in. The second part is the URI. You can use reqex as used above, or strings such as "&lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;". Basically, this stub_request is now waiting for a GET request to be made to a URI that matches the reqex /some.website.api/&lt;/p&gt;

&lt;p&gt;&lt;code&gt;with(header: {'Accept': '*/*', 'User-Agent': 'Ruby' }).&lt;/code&gt; In the second part, you can explicitly set the header information you want to match. If in your code you make a GET request to /some.website.api/, but the ‘User-Agent’ is something other than ‘Ruby’, then this stub_request will not be invoked.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;to_return(status: 200, body: '{"test": 0}', headers: {})&lt;/code&gt; Finally we reach the line that specifies what response we want when our code calls the API at /some.website.api/. In particular, we can set the status code (Here is 200 which means OK). The body, unsurprisingly, is the data returned to us. In can be one of the following types: [Proc, IO, Pathname, String, Array] . You can also explicitly set the headers of the response.&lt;/p&gt;

&lt;p&gt;To Summarize: By using the Webmock gem and the code above in your RSpec helper file, you can stop API requests made by your code and return whatever data you would like.&lt;/p&gt;

&lt;p&gt;More info here: &lt;a href="https://robots.thoughtbot.com/how-to-stub-external-services-in-tests" rel="noopener noreferrer"&gt;https://robots.thoughtbot.com/how-to-stub-external-services-in-tests&lt;/a&gt;&lt;br&gt;
Webmock Gem: &lt;a href="https://github.com/bblimke/webmock" rel="noopener noreferrer"&gt;https://github.com/bblimke/webmock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rspec</category>
      <category>rails</category>
    </item>
    <item>
      <title>Avoid Ransack's N+1 Pitfall!</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Wed, 17 Oct 2018 10:40:00 +0000</pubDate>
      <link>https://dev.to/husteadrobert/avoid-ransacks-n1-pitfall-33of</link>
      <guid>https://dev.to/husteadrobert/avoid-ransacks-n1-pitfall-33of</guid>
      <description>&lt;p&gt;I've written about &lt;a href="https://github.com/activerecord-hackery/ransack" rel="noopener noreferrer"&gt;Ransack&lt;/a&gt; before, because it's a handy, little gem for searching quickly through both models and their relationships.  But you may be surprised to know it's deceptively easy to create N+1 queries using Ransack!  The good news is, it's just as easy to fix.&lt;/p&gt;

&lt;p&gt;To review basic Ransack use, let's say you have a model &lt;code&gt;Service&lt;/code&gt;, which has properties for &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt;.  If you wanted to search both of those properties, you'd set up your view with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= search_form_for @q do |f| %&amp;gt;
  &amp;lt;%= f.label :name_cont %&amp;gt;
  &amp;lt;%= f.search_field :name_description_cont %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your controller would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def index
  @q = Service.ransack(params[:q])
  @services = @q.result(distinct: true)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty basic stuff, right?  But what if you have another model associated with Services?  For example, let's say you have a &lt;code&gt;Provider&lt;/code&gt; model with &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;address&lt;/code&gt; properties, and each &lt;code&gt;Provider&lt;/code&gt; has_many &lt;code&gt;Services&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, you want to search the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; properties for &lt;code&gt;Service&lt;/code&gt;, but you also want to include the &lt;code&gt;Provider&lt;/code&gt;s &lt;code&gt;name&lt;/code&gt; property as well.  How do you do that?&lt;/p&gt;

&lt;p&gt;Ransack provides an easy approach.  You can change your view to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= search_form_for @q do |f| %&amp;gt;
  &amp;lt;%= f.label :name_cont %&amp;gt;
  &amp;lt;%= f.search_field :name_description_provider_name_cont %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things are working smoothly.  But hold on, let's look at the SQL query that runs when we try to search for something:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F59sl4tj79vtcp5gqq7j0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F59sl4tj79vtcp5gqq7j0.png" alt="lots of sql queries" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yikes!  That's not what we want at all!&lt;/p&gt;

&lt;p&gt;Those familiar with rails will know the dreaded N+1 Problem, but will also likely know we can usually solve it with eager loading and using &lt;code&gt;includes(:model_name)&lt;/code&gt; . But where do we put it?  Easy, in the Controller of course!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def index
  @q = Service.includes(:provider).ransack(params[:q])
  @services = @q.result(distinct: true)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running our search again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u8ydoj13szt0guwtntk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u8ydoj13szt0guwtntk.png" alt="Much better!" width="800" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Please note that in my examples, I also have Sub Categories loading for another part of my view)&lt;/p&gt;

&lt;p&gt;This isn't a difficult problem to solve, but many may not be aware that using Ransack with associated models can end up creating this N+1 problems.&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>ransack</category>
      <category>rails</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Adding Models to an already large Codebase without using scaffold.</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Thu, 27 Sep 2018 08:45:49 +0000</pubDate>
      <link>https://dev.to/husteadrobert/adding-models-to-an-already-large-codebase-1531</link>
      <guid>https://dev.to/husteadrobert/adding-models-to-an-already-large-codebase-1531</guid>
      <description>&lt;p&gt;tl;dr&lt;br&gt;
Follow this Order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create an ERD&lt;/li&gt;
&lt;li&gt; Create a Migration&lt;/li&gt;
&lt;li&gt; Create the Model&lt;/li&gt;
&lt;li&gt; Manage Permissions to the Model&lt;/li&gt;
&lt;li&gt; Specify the Routes&lt;/li&gt;
&lt;li&gt; Create the Controller&lt;/li&gt;
&lt;li&gt; Create the Views&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're just joining a team of developers for the first time, it can be daunting trying to figure out where to start when adding functionality or new models.  There are hundreds of files of code and so many moving parts that you may or may not have any idea what they do.  While there is a lot of talk about TDD (Test Driven Development) and writing specs before writing any bit of code, I've found it helpful to create a basic prototype or skeleton of what I'd like before getting too deep into tests.  And the good thing is, adding models to an already large codebase is easy!&lt;/p&gt;

&lt;p&gt;There are many ways to develop, but I've found following a series of logical steps helps me.  So here is my general thought process and steps toward adding functionality to an already large codebase.  I won't go into major details for syntax(like how exactly to set up a migration), as you can google that information easily and I'm assuming the reader has a base knowledge of Rails.  Moreover, every codebase and team is different.  Instead, I'm focusing creating an overall guide to influence your decision process when you stand back and go 'what next?'  This post is aimed towards beginner developers who understand the basics about Rails but may not have enough experience yet to feel fully comfortable and to get to them to the point where they don't have to worry about setting things up and to get right into the 'real coding'.&lt;/p&gt;

&lt;p&gt;It should be noted that much of this work can be done using Rails &lt;code&gt;generate scaffold&lt;/code&gt; command from the command line.  However, if you're not 100% sure what exactly Rails will create and do, or if you're not yet comfortable creating basic scaffolding on your own, I suggest following these steps.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Create an ERD (Entity Relationship Diagram)
&lt;/h2&gt;

&lt;p&gt;Before you write any code at all, you need to plan out what exactly you're going to be creating.  You should take some time to figure out what type of model you will need, what attributes it will have, and how it will be related to other models within your codebase.&lt;br&gt;
Example ERD:&lt;br&gt;
 &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8uxbo5ui0kkd0b48xd3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8uxbo5ui0kkd0b48xd3t.png" alt="Imgur" width="535" height="313"&gt;&lt;/a&gt; Built at &lt;a href="http://www.draw.io" rel="noopener noreferrer"&gt;www.draw.io&lt;/a&gt;&lt;br&gt;
 Creating a solid ERD is argueably the most important step in the creation process, so take your time!  As the old adage goes, "Measure twice, cut once."&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Create a Migration!
&lt;/h2&gt;

&lt;p&gt;The first step for creating a new model is to prepare the database to store it's information.  If you're coming into a code base and have already gotten it working locally, then the databases (usually defined in your &lt;code&gt;config/database.yml&lt;/code&gt; file) have likely already been created.  So, you'll only need to create a migration.&lt;/p&gt;

&lt;p&gt;General syntax for Migration: &lt;code&gt;$ rails generate migration name_here&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a migration file for you, using the name you used in &lt;code&gt;name_here&lt;/code&gt; and adding a timestamp to it.  Open that file, and create the table you need with the fields you need. Note that the name of the table will be plural.  For example, if you wanted to create an &lt;code&gt;Article&lt;/code&gt; model, the name of the table in the database will be &lt;code&gt;articles&lt;/code&gt;.&lt;br&gt;
See: &lt;a href="https://guides.rubyonrails.org/v5.2/active_record_migrations.html" rel="noopener noreferrer"&gt;Active Record Migrations — Ruby on Rails Guides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When your migration file is finished, run: &lt;code&gt;$: rails db:migrate&lt;/code&gt;&lt;br&gt;
If for some reason you notice a mistake, or want to undo the changes, you can rollback with: &lt;code&gt;$: rails db:rollback&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After the migration runs successfully, you now have a table in your database to store the data for your new model!&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Create the Model
&lt;/h2&gt;

&lt;p&gt;Next, we will need to write the Rails code for the actual model.  Depending on your project, you may have various domains for models, but you can often find all the models you'll need in the &lt;code&gt;app/models&lt;/code&gt; directory.  Some things to note: the filename should begin with a lowercase letter and be singular.  The name of the class within the file should be uppercase and singular as well.  So, create a new file in your models directory with the name of your model.&lt;/p&gt;

&lt;p&gt;Let's look at an example.  Let's say you just created a new table &lt;code&gt;articles&lt;/code&gt; through a migration.&lt;br&gt;
In your &lt;code&gt;app/models/article.rb&lt;/code&gt; file(notice lowercase and singular)&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;That's it!  You now have a model.  Jump into the rails console (&lt;code&gt;$ rails c&lt;/code&gt;) to check that it's working as expected.  Don't worry about validations or relationships just yet.  Let's get everything working correctly first, then we can worry about wiring it all up.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Manage Permissions to use the Model
&lt;/h2&gt;

&lt;p&gt;Who will be able to use your Model?  By that I mean, will every user to your site be able to read information the model contains?  Will they be able to create new ones?  Or will you reserve the right to create new models only to admins?  If you're coming into a large codebase, likely there will already be some sort of User Authentication service (like Devise(&lt;a href="https://github.com/plataformatec/devise" rel="noopener noreferrer"&gt;GitHub - plataformatec/devise: Flexible authentication solution for Rails with Warden.&lt;/a&gt;)) and Resource Permission Management Service(like CanCan(&lt;a href="https://github.com/plataformatec/devise" rel="noopener noreferrer"&gt;GitHub - plataformatec/devise: Flexible authentication solution for Rails with Warden.&lt;/a&gt;))  &lt;/p&gt;

&lt;p&gt;Whatever library you use, you should look into how to add (or restrict) permissions to your Model.  In the case of CanCan, you will have an ability file in your &lt;code&gt;app/models&lt;/code&gt; directory.  Within that ability file, you can add permissions based on the type of user.&lt;/p&gt;

&lt;p&gt;For example, your ability file may look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserAbility
  include CanCan::Ability

  def initialize(user)
    can :read, Instruction
    can :manage, Gadget if user.admin?
    can [:show, :map], Restaurant
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not imperative to understand everything that's going on here, but you should look into how whatever library you use works when you can.  In CanCan's case, within an initialize method you specify what actions(in the Controller) a user can perform on a Model.  &lt;code&gt;:read&lt;/code&gt; is shorthand for &lt;code&gt;:show, :index&lt;/code&gt;, while &lt;code&gt;:manage&lt;/code&gt; allows for all normal CRUD actions.  If you have other actions you will need to perform, you can add them as well by using an array of symbols.&lt;/p&gt;

&lt;p&gt;If you're not sure, for the time being you can just add your model and allow the user to &lt;code&gt;:manage&lt;/code&gt; and change it later, but you should think about who exactly will be using the model and what they will be doing with it. &lt;/p&gt;

&lt;p&gt;This step is must be completed now because if you do not give permission to access the Model, you won't be able to test your controllers or views later.  Each request to use the resource will be stopped by the Application controller and you'll get an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Create your Routes
&lt;/h2&gt;

&lt;p&gt;After you've given permission to access the model, you'll need to define the route a user will take to reach that resource.  It's easy to forget setting up routes, so I find doing this before creating controllers and views to be a logical next step in the process.&lt;/p&gt;

&lt;p&gt;Within your &lt;code&gt;config/routes.rb&lt;/code&gt; file, you'll need to specify the routes that will access your controller(which we will make next).  If your application uses many namespaces, you should take care that you specify routes within the correct namespace or nested within the proper related resource.  Also, you'll need to specify any actions that fall outside the realm of the normal CRUD actions.  If you nested the routes within another resource, take note of it, as you'll need that information for the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Create the Controller
&lt;/h2&gt;

&lt;p&gt;Finally we can create the Controller for our Model.  You may already be worried about all the functionality or data parsing or logic you know you'll need to add, but don't worry about all that yet!  All we should worry about right now is making sure that when we put in a URL, our application reacts as expected and routes our request to our Controller.&lt;/p&gt;

&lt;p&gt;First, we must create the Controller file, and this can be a little tricky.  If your Controller is not nested within a namespace or other resource, you can just create a new file in your &lt;code&gt;app/controllers&lt;/code&gt; directory.  However if your Controller IS nested within another resource, you'll need to either create directory for your new Controller, or be sure to create your Controller within the proper directory if it already exists.&lt;/p&gt;

&lt;p&gt;In the proper directory, create a new file to serve as the controller.  This file will need to follow the basic naming structure of the plural of your model + underscore + controller.  For example, &lt;code&gt;articles_controller.rb&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;In your Controller, define all the actions the Controller will have.  You don't need to add any logic to them; just define them.  This example is for a non nested resource.  Note the Model name is in uppercase, plural, and there is no underscore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ArticlesController &amp;lt; ApplicationController
  def show; end
end  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your controller is nested, you'll have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AdminDomain::ArticlesController &amp;lt; AdminDomain::ApplicationController
  def show; end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A couple things to note: Remember that the &lt;code&gt;AdminDomain::ArticlesController&lt;/code&gt; is NOT inhereiting from something called AdminDomain.  The &lt;code&gt;::&lt;/code&gt; is a scope resolution operator, and is serving to tell the compiler that this ArticlesController is located within the AdminDomain, not that it inherits anything. The inheritance is shown after the &lt;code&gt;&amp;lt;&lt;/code&gt;, which states the &lt;code&gt;AdminDomain::ArticlesController&lt;/code&gt; inherits from &lt;code&gt;AdminDomain::ApplicationController&lt;/code&gt;, but you could just as easily have it inhereit from &lt;code&gt;WriterDomain::ApplicationController&lt;/code&gt; or &lt;code&gt;ApplicationController&lt;/code&gt; (thought this would likely lead to unexpected behavior.)  Also, it's technically unnecessary to define blank methods as Rails is kind enough to do default actions without an explicit method declaration.  But for clarity sake (and for you to double check what methods you'll have), I suggest declaring them.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Create the Views
&lt;/h2&gt;

&lt;p&gt;The default behavior for an action in a controller is to render the view that shares the same name.  So, with our blank actions declared in the controller, we should go about making our Views.  Like with the controller, you will need to remember if your resource is nested or not.  If not, you can simply create a folder in your &lt;code&gt;app/views&lt;/code&gt; directory that is the plural of your model name.  For example, you would create a &lt;code&gt;app/views/articles&lt;/code&gt; directory for all Article views assuming the ArticleController is not nested inside another resource.&lt;/p&gt;

&lt;p&gt;Inside your new directory, create a blank file for your view, and give it the file name that reflects the action in the controller.  Rails uses ERB out of the box, but check what templating language your team uses and create a file that ends with that extension.&lt;br&gt;
For ERB, &lt;code&gt;app/views/articles/show.html.erb&lt;/code&gt;&lt;br&gt;
For HAML, &lt;code&gt;app/views/articles/show.html.haml&lt;/code&gt;&lt;br&gt;
etc.&lt;/p&gt;

&lt;p&gt;For now, just add a single line in the file to make sure it's working properly. Something like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should be able to put in the URL for the show action of the Topics Controller (check your routes if you're not sure how to access it), and recieve a large "Hello World!" response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start Coding!
&lt;/h2&gt;

&lt;p&gt;You're all done!  That is to say, you've just started.  But you've done all the basic work required to add a Model, Controller, Routes, and Permissions to the codebase.  Now you can start worrying about more practical matters, like how you want the page to look, or what data you want to query from the database, or what data you want the Model to validate, the tests you'll need to create, or any of the other concerns that come with creating new functionality.&lt;/p&gt;

&lt;p&gt;Good luck and happy coding!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>beginners</category>
      <category>basics</category>
    </item>
    <item>
      <title>Creating Ransack params without search_form_for</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Thu, 27 Sep 2018 08:23:14 +0000</pubDate>
      <link>https://dev.to/husteadrobert/creating-ransack-params-without-searchformfor-4k8l</link>
      <guid>https://dev.to/husteadrobert/creating-ransack-params-without-searchformfor-4k8l</guid>
      <description>&lt;p&gt;Sometimes you have a search box in one area, but you want to display the results of that search with a totally separate controller and view.  It can be a little confusing trying to do so with a gem like Ransack, so this tutorial aims to give a basic run down of how you could implement search in one controllers action, and display the results in another controllers action.&lt;/p&gt;

&lt;p&gt;First, you'll need to ensure the Ransack gem is in your Gemfile and you run &lt;code&gt;bundle install&lt;/code&gt;.  You can find further documentation for Ransack here: &lt;a href="https://github.com/activerecord-hackery/ransack" rel="noopener noreferrer"&gt;GitHub - activerecord-hackery/ransack: Object-based searching.&lt;/a&gt;  This tutorial assumes basic knowledge of how to use Ransack.&lt;/p&gt;

&lt;p&gt;Normally, when using Ransack, you'll have a form that uses the &lt;code&gt;search_form_for&lt;/code&gt; helper that Ransack provides.  Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# in index.html.erb

&amp;lt;%= search_form_for @q do |f| %&amp;gt;

  # Search if the name field contains...
  &amp;lt;%= f.label :name_cont %&amp;gt;
  &amp;lt;%= f.search_field :name_cont %&amp;gt;

  &amp;lt;%= f.submit %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in your controller you'll have something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# in ItemsController.rb

def index
  @q = Person.ransack(params[:q])
  @people = @q.result(distinct: true)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty standard stuff.  But what if you want to render a different view with the Ransack results?  For example, you want to send users to a specific 'Search Results' page using your Search Controller?&lt;/p&gt;

&lt;p&gt;To do this, you'll need to get the search query from the user and format it in a way that Ransack wants to receive it using basic form helpers.  Specifically, Ransack wants a parameter with the key 'q', which contains the value of another hash.  The hash value of 'q' is a single key value pair where the key is a string containing the methods for how Ransack should look for the object, and the value of that key is a string that is the actual search query from the user.&lt;/p&gt;

&lt;p&gt;Basically, your params variable should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;params = {"q": {"name_or_description_or_id_cont": "Actually query from the User"}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create this 'q' param that Ransack expects explicity with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# in whatever view you'd like users to search from

&amp;lt;%= form_tag search_path, method: :get do %&amp;gt;
  &amp;lt;%= text_field_tag :"q[name_or_description_or_id_cont]" %&amp;gt;
  &amp;lt;%= submit_tag "Search", data: { disable_with: "Searching..." }
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This form will create our 'q' param and format it in the way Ransack wants it, and send it along to whatever Controller and Action you set up in your routes.  You can of course change the &lt;code&gt;name_or_description_or_cont&lt;/code&gt; to whatever fits your needs.&lt;/p&gt;

&lt;p&gt;In the Controller you want to use to display the results, you will have the normal Ransack process&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # in whatever controller you'd like to handle the search request

  def search
    @q = Item.ransack(params[:q])
    @items = @q.result
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now use the &lt;code&gt;@items&lt;/code&gt; instance variable in your view to display the results of the query.&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rails</category>
      <category>ransack</category>
    </item>
    <item>
      <title>How to add "Preview Mode" style functionality to a Rails application</title>
      <dc:creator>Robert Hustead</dc:creator>
      <pubDate>Sun, 23 Sep 2018 11:35:42 +0000</pubDate>
      <link>https://dev.to/husteadrobert/how-to-add-preview-mode-style-functionality-to-a-rails-application-39f</link>
      <guid>https://dev.to/husteadrobert/how-to-add-preview-mode-style-functionality-to-a-rails-application-39f</guid>
      <description>&lt;p&gt;Implementing a 'Preview Mode' style functionality is deceptivly simple in Rails.  Let's assume we have an application where we introduce items to customers.  We have a normal customer domain, and a back end Admin domain where we perform basic CRUD actions like creating, editing and updating items with information.&lt;/p&gt;

&lt;p&gt;Now, our writers want the ability to preview the item they are creating to see how it will look when published.  However, we don't want normal users to be able to access our draft items.  If a user visits an item page that's a draft, they should get a 404 error.  However, writers should be able to visit an item page that is a draft to see how it will look (with a banner or something indicating that the page is in preview mode).  &lt;/p&gt;

&lt;p&gt;Let's implement that functionality.  This tutorial will use Cancan for resource authorization, but it can be changed based on whatever library you currently use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Status column to your Model.
&lt;/h2&gt;

&lt;p&gt;First, we should add a &lt;code&gt;status&lt;/code&gt; column to our model.  In practice, this column should have either values "draft" or "published".  So, this column should be of type String, and given a default of "draft" so newly created items are not displayed by default.  Also, we should set it so that null is not acceptable.  The following migration will work for our purposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # In your Migration file

  def change
    add_column :items, :status, :string, default: "draft", null: false
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Update the Model
&lt;/h2&gt;

&lt;p&gt;In your &lt;code&gt;item.rb&lt;/code&gt; model file, we should add some Constants for our statuses, as well as a scope to access them easily in our views.&lt;/p&gt;

&lt;p&gt;For our Constants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # In item.rb

  STATUS_PUBLISHED = "published".freeze
  STATUS_DRAFT = "draft".freeze
  enumerize :status, in: [STATUS_PUBLISHED, STATUS_DRAFT]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And scopes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # In item.rb

  scope :published, -&amp;gt; { where(status: STATUS_PUBLISHED) }
  scope :draft, -&amp;gt; { where(status: STATUS_DRAFT) }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Change the Items#show lookup method
&lt;/h2&gt;

&lt;p&gt;We need to change how our Items controller looks up items.  You're likely already using a resource authentication library (like CanCan), but we will need to bypass that default functionality.  In the case of Cancan, be sure to exclude the show action from any loading and authorization of resources.&lt;/p&gt;

&lt;p&gt;We want to see if there is a 'draft' param being passed to the controller.  If so, we can look for our item in all of the Items.  If the request is not looking for a draft, then we should only look in published Items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def show
    items = params[:draft].present? ? Item.all : Item.published
    @item = items.find(params[:id])
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's assume we have an item with id: 4, and it's status is &lt;code&gt;draft&lt;/code&gt;.  If a user visits ~/items/4, they will get a 404 error (because &lt;code&gt;services.find(params[:id])&lt;/code&gt; will turn up nothing because it's only looking in &lt;code&gt;Services.published&lt;/code&gt;).  However, if your writers access ~/items/4?draft=true, they will be able to see the item in draft mode.&lt;/p&gt;

&lt;p&gt;What about normal users looking up the above url, and they add ?draft=true to it?  Won't they be able to see the item in draft mode?  That's not what we want at all.  Let's make sure only our writers can access that page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update CanCan(or whatever library you use) to remove permission from Normal Users
&lt;/h2&gt;

&lt;p&gt;You need to ensure that normal users are only given read access to items with a status of "published".  Check the documentation for your authorizaion library of choice, but for Cancan you may have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# in models/ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.type == "writer"
      can :manage, Item
    else
      can :read, Item do |item|
        item.status == Item::STATUS_PUBLISHED
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, this ensures that non "writer" users will be able to see Items.  However, the only items they will be able to see are those that are published.  So, if a user attempts to access ~/services/2?draft=true, Cancan will stop them before the ItemsController attempts to find the record.&lt;/p&gt;

&lt;p&gt;We now have all the back end code for "Preview Mode" style functionality.  All that remains is updating our Views.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add the Ability to Update the Item Status
&lt;/h2&gt;

&lt;p&gt;Wherever you have your form setup to create items, be sure to include a selector to choose if the item is in draft mode, or published. &lt;/p&gt;

&lt;p&gt;Or, you could use buttons when the writer is saving an Item.  The choice is yours, but be sure to give writers the choice when saving Items.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update Views for Writers and Normal Users
&lt;/h2&gt;

&lt;p&gt;In the Admin domain, add a way to access the draft view with something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# in views/admin/items/index.html.haml

# when displaying all the Items
%li= link_to "Preview", service_path(service, draft: true), target: "_blank"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we link to the services page in the normal user domain while also including the &lt;code&gt;draft&lt;/code&gt; param set to &lt;code&gt;true&lt;/code&gt;.  If you remember, this was used in the ItemsController to decide wether to look up from all Items, or only published Items.&lt;/p&gt;

&lt;p&gt;In normal users views, if you're displaying services in places other than Item#show, be sure that you only display services that are published.  Use the previously created &lt;code&gt;published&lt;/code&gt; scope wherever you display services to users.&lt;/p&gt;

&lt;p&gt;For example if you want to list all the items related to a category, you might have had something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@category.items.each do |item|
  #display code
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But you need to change it to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@category.items.published.each do |item|
  #display code
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add something to the top of Draft Views
&lt;/h2&gt;

&lt;p&gt;Finally, we want something to signify to writers that the service they are looking at is in Preview mode.  In the normal Service#Show view file, add some HTML at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- if params[:draft].present?
  %p.draftMessage You are in Preview Mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update the CSS to look however you see fit!&lt;/p&gt;

&lt;p&gt;There you have it!  You've now emplemented a basic "Preview Mode" feature into your application.  Good luck and happy coding!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
