Copy Paste Error with Rspec

software ruby on rails

Everyone loves laughing with others about their mistakes. Let’s laugh at me for a second here.

I test my Rails applications with RSpec. While editing the users factory for 2 new user types, I copied lines 19-23 in the image below. I changed the factory name to the 2 added user types, saved and closed the file. I then proceeded to update the users controller spec to test the permissions of these two new user types. Between not being confident in my RSpec skills and getting some false positives, I couldn’t figure out why some tests passed and some failed. After way too long, I finally found the problem. Can you?

Copy/Paste normally saves time but in this case it definitely didn’t. Always double check your code, friends. 🤦‍♂️

Chris Francis
Software Developer, BiteSite

Carrierwave-AWS and fixing Excon::Errors::SocketError Broken Pipe Errors

custom software software development ruby on rails

So we've been using Carrierwave for a while. It's an amazing solution for Ruby on Rails apps that need to store files.

We use it mainly with Amazon AWS S3 as our storage. However, recently when trying to use it for a new app, we kept running into these errors anytime we tried to upload anything to S3. The errors were Excon::Errors::SocketError Broken Pipe errors. Most posts on the internet suggest issues with permissions or with not setting the region properly, but after trying all those, we still couldn't get it to work.

We then came across a Stack Overflow answer that talked about using an alternative gem called Carrierwave-AWS.

I was skeptical at first, because I wasn't sure who was maintaining it and why I hadn't heard of it before. As it turns out, this is maintained by the same people who maintain the original CarrierWave!

This new library uses the official AWS-SDK library and actually solved my Broken Pipe issues! What's more, I was happy to see that I could still revert to using file storage for dev environments with this library. All pretty sweet!

So if you're using Carrierwave with AWS S3 and you haven't heard of Carrierwave-AWS, it's probably a good time to check it out!

Here's the link: https://github.com/carrierwaveuploader/carrierwave-aws

Enjoy!

Casey Li
CEO & Founder, BiteSite

Ruby on Rails Templates

software development ruby on rails

As a junior Ruby on Rails developer, GoRails has been a great help with all their free video tutorials Chris Oliver creates. When I started to venture into rails templates, I found he hosts a repository of community created rails templates for others to upload or use for free.

Check it out here if you're a Rails developer and are interested in automating some of your workflow. https://railsbytes.com/

Chris Francis
Software Developer, BiteSite

Ruby on Rails CSS File Structure

css software development ruby on rails

Ruby on Rails is an amazing framework. At BiteSite, we started using it back in 2011 and haven’t stopped since. It’s combination of technical ability and software philosophy has kept it our framework of choice when it comes to web development and it only gets better with time.

One of the things we appreciate most about Ruby on Rails is its convention over configuration philosophy. In short, it basically says, “If you follow our conventions, you don’t have to configure your code”. This allows for less boilerplate code and is, in my opinion, the best way to enforce coding conventions.

With convention over configuration, one of the best benefits you get is a well designed architecture for your code. Every Rails app puts all of its controllers in the same folder, all of its models in the same folder and so on. It makes developing Rails so easy to jump into.

That being said - it’s not perfect. While convention over configuration is in so many places in Ruby on Rails - there are areas it doesn’t exist and you’re left to come up with your own design or structure.

One of these places is CSS.

While Rails does suggest how to structure your CSS when you use scaffolding, it doesn’t really have a strict convention over configuration policy about how to split up your CSS into multiple files and where to put them (aside from the ‘stylesheets’ folder).

When apps get big, this can become a problem.

Over the years, we have come up with a system that has served us pretty well that we thought we’d share. It’s not perfect, but it does work.

Definition

To be clear, this system only dictates how to split up your files and where to put them. It does not cover how to actually structure your CSS selectors and CSS code within those files.

Driving Forces

When we set out our to improve our CSS File structure, there were really two driving forces. One, as with most coding, we wanted our code to be DRY (Don’t Repeat Yourself) where possible. Now, notice I said “where possible” vs. “as much as possible”. We found that overtime, it was hard to keep track of CSS code and so many times you would change some CSS code to fix one problem, but not realize it was being used in 5 other places. We were consistently breaking pages without realizing it and so we implemented our second driving principle: make our file structure easy to follow and easy to figure out what pages it was affecting.

We realized this was breaking DRY code, but it kept our codebase sane and predictable.

(Incidentally, we found out later on, that this true separation of concerns vs separation of technologies was being embraced in future frameworks like React and Vue where you can scope CSS to individual components).

SCSS vs CSS

Note, at BiteSite, we use SCSS to help with a lot of this, but a lot of the learnings can be applied to vanilla CSS.

CSS File Structure

With those two driving forces in places, we came up with the following CSS file structure:

app
↳ assets
  ↳ stylesheets
    ↳ base
    ↳ common
    ↳ components
    ↳ views

The 4 folders we’ve introduced are base, common, components, views. Let’s explore each of these.

base

The base folder is where we put our UI Kit CSS. So all your standard buttons, links, typography, tables and other CSS that would apply to most or all web apps we put in here. To complement this, we also include things like globals and colorswatches which we can import into the rest of the files. We’ll usually split each of these into its own file. Examples include:

app
↳ assets
  ↳ stylesheets
    ↳ base
      ↳ globals.scss
      ↳ colorswatches.scss
      ↳ buttons.scss
      ↳ links.scss
      ↳ typography.scss
      ↳ forms.scss
      ↳ tables.scss

common

The common folder is how we achieve ‘DRY’ code outside of UI Kit elements. While we generally try to scope our CSS to specific pages (or components if using React), there are definitely some cases where it’s better to re-use CSS within HTML/JS code. We have a dedicated folder for these to help remind developers. It tells the developer, “Hey, if you’re editing something in the common folder, be careful, because it most likely affects more than just the part of the web app that you’re working on.” Additional to some reusable CSS that’s specific to your app, we also include things like layout CSS here. Examples include:

app
↳ assets
  ↳ stylesheets
    ↳ common
      ↳ layout.scss
      ↳ shopping_cart_line_item.scss
      ↳ pricing_badge.scss

components

This is specific to web applications that use Webpacker + React. If you don’t use React, you can skip this part. When we create components and want to scope some CSS specifically to the component. Now I’m sure there are better JS ways to do this, but to be honest we haven’t quite figured them out yet, so we do this instead.

To make this work, we add a CSS ID/class selector to the outer most element of the component that starts with “component-”. Here is an example:

/* product_card.jsx */
…
function ProductCard() {
  return (
    <div className=’component-product-card’>
      …
    </div>
  );
}

Then we place it’s corresponding CSS in this folder:

/* app/assets/stylesheets/components/product_card.scss */
.component-product-card {
  …
}

views

This is the last folder and we use this for page specific CSS. To do this scoping, we surround every view template in a <div> or <span> that has an ID in the form of “controller-view”. Here is an example:

<!-- app/views/products/show.html.erb -->
<div id=”products-show”>
  ...
</div>

With the page scoped, we then place the CSS files in a file structure that’s similar to the regular app/views/ folders. We create a folder for each controller and a file for each view.

/* app/assets/stylesheets/views/products/show.scss */
#products-show {
  ...
}

Conclusion

We’ve been using this file structure for over 5 years now and while we know of some shortfalls (e.g. React components named the same but within different folders), it has worked out very well for us. Hopefully this will help others as well!

Casey Li
CEO & Founder, BiteSite

RSpec with Resque

software development ruby on rails resque rspec

So one of the gems we use a lot in our Ruby on Rails applications is Resque. For those who don't know, it's a library that allows you to run background tasks that are separate from the main web thread.

This gets especially useful when your web applications get big enough that they are doing long, complex tasks. There are alternatives like Sidekiq and Delayed Job, but Resque was the first one we came across and it's been serving us well for years.

However, one thing that became really annoying to deal with was automated tests (or specs). We use rspec, and when we would run our tests, a lot of the times our tests would fail because it would run into some code similar to Resque.enqueue which requires that your Redis server be running.

One way to deal with this was to simply start up your Redis server and then run your specs. However, this didn't feel right. With stubs, and mocks, and whatever else you use to fake logic, it seems that it should be easy to stub out any call that Resque makes.

Luckily, there is an easy solution.

It's called resque_spec and its repo can be found here.

It can actually do a bunch of stuff, but the key thing for us, is that it basically stubs out the real Resque calls so it doesn't actually queue up jobs, and doesn't require Redis to be running. What's more, the setup is as simple as including it in your Gemfile. Warning: As they mention, only include this in your test group, as it does override the default Resque functionality

# Gemfile

...
group :test do
  gem 'resque_spec'
end
...

What's more, if you're using Resque Scheduler, it works with that as well (with a little extra configuration).

With resque_spec in place, running specs became a lot simpler. Hope this helps some peeps out!

Casey Li
CEO & Founder, BiteSite