Category Archives: Open source

Consider Turbolinks 5 for your next Rails project

Turbolinks 5 is a library for web applications that makes pages load faster. Here’s how:

  • When the user navigates, it replaces only the body of the page (and merges the headers) with AJAX, instead of doing a full page load
  • If the user navigates to a page that they’ve already viewed in that session, it displays a cached version and then checks for new content in the background

These features make your app appear at least 2x as fast to the user.

You could realize similar preformance benefits with a client-side app written in a JavaScript MVC that talks to the server through an API.

Turbolinks’ genius is that delivers the improved user experience of a client-driven app without you having to write a client-driven app.

Consider it, every time

You should strongly consider Turbolinks 5 for any new Rails project.

I didn’t consider previous versions of Turbolinks. Superficially, they seemed buggy. Turbolinks 5 is a full rewrite, and it’s been running swimmingly in production for Basecamp 3 and my little project, TourExec.

Why consider Turbolinks now?

Because your users deserve the fastest possible experience, and you deserve to ship quickly.

When I built TourExec, a tour booking platform, I wanted an excellent booking experience for customers. Simply, they choose a time and how many they are, and the app displays available times. Then, hopefully they click a time and book.

Booking a tour

Notice in the interaction there is no page reload. The user chooses a date, and the times dynamically update. When the user clicks a time, the booking form appears almost instantly.

This is driven by Turbolinks. I didn’t write any JavaScript to retrieve and display times based on the selected date. I only wired the list selectors to “refresh” the page when the user changed them. Turbolinks takes care of the rest, retrieving the new page body from the server and swapping it out.

This is the most advanced implementation of Turbolinks in my app. The rest of its benefits apply without any extra work.

My admin interface for businesses is super snappy, thanks to Turbolinks. At the point of sale with a line of customers waiting, a business benefits from a tour roster that loads in a third of the time.

Pairing Turbolinks with a JavaScript MVC

I pull in React for some particularly interactive features, like a schedule builder that lets businesses define their tour times. In that case, it was easier to write React components than figure out a server-driven approach that delivered an acceptable experience.

Too often, frameworks like React grow to take over an entire application without a true analysis of the pros and cons.

In the case of TourExec, Turbolinks delivers a speedy experience throughout, and I bring in React for particular needs. This balance allows us to move quickly and reduces technical debt down the road.

The trade-offs

Nothing is without a trade-off. Turbolinks won’t work effortlessly with every JavaScript plugin, but its developers have documented how to adapt, and I’ve found it very doable.

Retrieving RSS with JavaScript

I’ve open sourced RSS to API, which allows you to retrieve RSS feeds via JavaScript. With a few clicks, you can deploy it to Heroku and start consuming RSS from your JavaScript code!

Almost any site with an RSS fee returns a reverse-chronological list of items, each containing a title, link, and date. This consistency can be powerful. You can create a dashboard with the latest feed item(s) from multiple sites. You can bring your corporate web site’s news items on your intranet. The possibilities are limited only by what is available online.

In many cases, it makes sense to grab RSS feeds via JavaScript and display them in the browser. However, cross-domain restrictions generally prevent direct retrieval of feeds via JavaScript. The Google Feed API provided an easy way to retrieve feeds with JavaScript, but it was deprecated in April of 2015 and could disappear at any moment. Alternatives like the Feedly API do not accept requests directly from JavaScript.

To consume RSS in JavaScript, it’s necessary to route it through a server. Your JavaScript communicates with a server, which retrieves the feed and returns it. Google Feed API is going away, and it’s a pain to build your own, so I’m releasing RSS to API. It’s a lightweight Ruby app that accepts requests for feeds and implements caching to serve them quickly. With just a few clicks, you can deploy it onto Heroku’s free plan (you’ll want to up your plan to use this in production).

RSS to API has been tested with dozens of feeds on one page. See the example below, which might lag because Heroku’s free plan has to go to sleep once in a while.

See the Pen RSS to API Example by csm123 (@csm123) on CodePen.

Why React JS matters for developers

It can be tempting to think of React JS as just another JavaScript framework, along the lines of Angular JS and Ember JS. This entirely misses why it was created and the problems it solves.

React is not designed to solve problems specific to web applications. Rather, it is designed to solve problems for all applications.

This sounds like buzz until you look at where React is going. Its first uses were in web applications, specifically Facebook and Instagram. Now, though, it’s rapidly moving past that:

  1. Facebook used it to build a native iOS mobile app, and is open sourcing react-native to allow anyone to do the same for iOS and Android. Learn more from Facebook’s recent React conference: overview, deep dive.
  2. Flipboard used it to power canvas graphics on its web site, which unlike the traditional browser DOM can operate with video-like smoothness. They open sourced this add-on to React.
  3. Netflix uses it to create TV interfaces. Hear about it in their own words.
  4. It’s used on both the server-side and the client-side. React doesn’t need a web browser to work.

Why is React gaining traction on so many platforms, unlike other JavaScript frameworks?

It’s simple: React presents a better model for development, generally.

React’s impact is best explained by its side effects:

  1. Your code is clear. It is arranged into components, each with its own defined responsibility.  Learn more about structure.
  2. Your app is predictable. It’s very clear where data flows, and what happens when a user does something. Learn more about data flow.
  3. Your app is fast. React is really, really fast, creating a better experience for users, even if you have a ton of data. See this example.
  4. Your app is standards-based. React adds layers only when it needs to. You feel like you are actually writing JavaScript and HTML, not some magic template language.
  5. Surprise, you’re an app developer. React breaks down barriers across platforms, by applying its same model across the board. This means that once you learn the React way of structuring an web application, you have a huge head start on developing a native iOS or Android app, thanks to react-native. Surely this will happen to other platforms.

So, get to know React, even if you don’t see a need for it in your current projects. Far more than a shiny new JavaScript framework,  it could represent a new standard for structuring applications.

See also, the benefits of adding React to a real-world Rails app, and a deep dive into React in Rails.

Finally, check out the React JS Conf 2015 videos.

User announcements for Ruby on Rails with the Starburst gem

If you have an app with users, chances are you need to make announcements to them from time to time.

Starburst allows you to show messages to logged in users within your Rails app. Once the user closes the message, they won’t see it again.

You can target messages to particular groups of users, based on their database attributes or your own methods on the User class. For instance, you might send a message only to users on your premium plan.

Starburst remembers on the server who has closed which message. Therefore, a user who closes a message on their desktop won’t see it again on their mobile device. Starburst doesn’t use cookies, so a user won’t see an announcement they’ve already read if they switch devices or clear their cookies.

Starburst is in production on Cook Smarts, where it has served announcements to thousands of users.

Find out how to install and use Starburst on its GitHub repo, and post an issue there with any feedback!

Creating a Ruby gem for one-time announcements, part 4 – performance, views

I’m developing a gem to deliver one-time announcements to users in Rails apps. See the previous parts of this series for some background.

Now, in part 4, we’ll test performance performance and add a view to show the current announcement.

Measuring performance

How much work does the gem have to do in order to retrieve the latest announcement for the current user?

Database calls are often a performance culprit. Queries should be small in number (see N + 1 problem) and minimally taxing on the database.

The gem runs only one query to retrieve the latest announcement.

To see how long that query lasts, we’ll run the method that calls it in the Rails console. The current method of the Announcement model checks for an announcement for the current user.

What if we have 1,000 announcements and 50,000 users? There are a few ways to test performance of a specific method, one of which is a benchmarking gem from Viget Labs. I used Ruby’s built-in benchmark module.

The call to Announcement still comes in at under 1 ms with 10,000 users and 5,000 announcements.

Showing announcements

A view helper called current_announcement will call the current announcement from the model.

Then, the developer using the gem can pull in the current announcement through a view partial.

We still need to let the user close the announcement, and remember the announcements that each user has read.

Integrating with Foundation and Bootstrap

At Cook Smarts, we use Zurb Foundation, and it’s served us well.

The gem will include templates for announcements using Foundation’s and Bootstrap’s existing styles.

It will also include a template for sites that do not use either framework. In that case, it is up to the developer to style the announcements in the app’s CSS.

What’s next

Next, we’ll talk about remembering which announcements have been read by the current user, security, and how site administrators can add announcements.

Searching across tables with Wice Grid in Rails

Say that in your Rails app’s admin interface you have a table of orders, each of which is associated with a customer. You need to find orders belonging to a particular customer, by e-mail address. This is a search across two tables, orders and customers.

Wice Grid, a fantastic data grid for Rails, makes this search easy. Check out our intro to Wice Grid if you haven’t already, then come back here for this trick.

In your controller, when you declare your grid, include the other table that you’re searching.

Now, in your view, when you define the column that contains the customer’s e-mail address, reference the model (Customer) and the field within that model (email).

Wice generates a search box above the customer e-mail column. Enter an e-mail address to find orders a associated with that customer.

Try out Wice Grid in your Rails app! It makes admin interfaces much easier to build.

For more background, check out our intro to Wice Grid.

If you’re building a broader search feature for your app’s users, check out our intro to full-text search in Rails.

Creating a Ruby gem for one-time announcements, part 3 – targeting messages to users

This is part 3 of building a gem for targeted, one-time announcements to users in Rails. See part 2 and part 1.

We’ll focus on targeting announcements to certain types of users. For instance, the admin may want to deliver an announcement only to users who have subscriptions.

A field in the Announcements table called limit_to_users will specify which types of users should receive the announcement.

limit_to_users can contain multiple conditions, so we’ll make it an array of hashes. ActiveRecord allows objects like these to be stored in text fields in the database, using the serialize method in a model.

This test validates that the field works as intended, storing conditions and allowing them to be retrieved. Here, we are sharing the announcement only with users who do not have a subscription.

Querying serialized fields is tough

It’s risky to query serialized fields in a relational database. MongoDB and similar noSQL databases are tuned for fast queries of free-form information, while Postgres and its SQL siblings are not.

We need to figure out which announcement to serve to which user, even though the conditions are stored in a query-resistant serialized field.

Houston, we’ve got loops

Maybe we should grab all active announcements that the current user has not read, and cycle through them to find the latest one that is relevant to the user.

My first try at this includes two loops, one inside the other, which:

  1. Cycle through each active, unread announcement
  2. For each announcement, cycle through each condition

Loops carry potential performance issues, especially when nested. In this case, we came as far as we could with a query, and used loops for the rest.

The loops do not re-query the database, thus avoiding an n+1 query problem, so they should be pretty quick. We’ll test performance in past 4, coming soon.

Creating a Ruby gem for one-time announcements, part 2 – TDD, marking as read

In part 1, I talked about the need to announce things to users in a Rails app. The announcements should be scheduled, shown to each user only once, and targeted to particular types of users.

We’re building a Ruby gem to enable this.

Tests

I started by writing tests, describing what the one-time announcements gem should do. Test driven development (TDD) can be controversial, but I find that it helps me plan and identify issues earlier in development.

I learned how to test from Everyday Rails Testing with RSpec. The author continually updates it as new versions of Rails and RSpec are released.

The first tests confirm, at the model level, that announcements can be:

  1. Created
  2. Scheduled
  3. Marked as read

These tests pass with the current Announcement model:

Marking announcements as read

Each user should see a particular announcement only once, so I needed a way to mark announcements as read.

The unread_by scope above shows only those announcements which the user has not read. It uses the AnnouncementView model to see who has read which announcements:

The current method chains the ready_for_delivery, unread_by, and in_delivery_order scopes to determine which announcement to deliver.

This StackExchange thread helped, and I took inspiration from a gem specifically for marking messages as read.

What’s next

In part 3, we’ll look at how to target announcements to particular types of users. For instance, what if you have an announcement just for users on a particular subscription plan?

Creating a Ruby gem for one-time announcements – part 1

At Cook Smarts we need a way to provide one-time announcements to customers, right inside our Rails app.

For instance, we may want to notify our paying users of a new feature when they log in.

Once the customer reads the announcement, he or she can close it and will never see it again.

The closest Ruby gem I could find is thoughtbot’s paul_revere. It’s elegant and simple, providing one-off announcements to an app.

It does not, however, support:

  • Start and end dates for an announcement What if an announcement is relevant only for a period of time?
  • Announcements to a subset of users What if an announcement is relevant only to some users?
  • Remembering across devices that a user closed a message If the user already read a message on desktop, why should they see it again on mobile?

What about keeping it simple?

One-off announcements may seem simple at first, but in practice, they benefit from more granularity.

Showing people only the announcements they need, at the right time, and only once, increases the messages’ potency.

Filtering announcements by user characteristics

Each announcement will be filtered based on conditions about the current user. For instance, is the user on a free trial or paid plan? When they did they sign up?

Perhaps we need to grab all announcements the user has not read with a simple database query, and then use some logic to see which of those is relevant to the user.

In any case, I’m looking for a safe, customizable way to target one-time messages.

What’s next

Next, I’ll take you through the process of creating a Ruby gem for one-time announcements. Stay tuned for part 2…

Easy data grids for your Rails app, with Wice Grid

Sometimes we need to show tables of data in a Rails app, sort of like souped-up spreadsheets. The tables, or grids, should handle tons of records, support searching and filtering, and allow for customization.

Ever try coding a data grid yourself? It’s hard. You need to implement pagination, filtering, searching, ordering, etc., every time. Why not use a pre-built solution and built off of it instead?

Wice Grid is the quickest grid solution out there for Rails. It takes care of both the client and server. It’s not AJAX-y and gorgeous, but it’s functional and reliable.

At Cook Smarts, we used Wice Grid to improve the admin interface without leaping to a full-scale solution like Rails Admin.

For instance, Cook Smarts’ customers can purchase gift certificates for their friends. Site admins need to see all gift certificates and search for particular ones. The easiest way for them to do this is through a data grid.

To get started, check out the Wice Grid page on GitHub.

Getting up and running is easy:

Follow the installation instructions on the Wice GitHub page

Add the grid code to a controller method, with the model whose data should appear in the grid.

Then, add the grid code to a view, referencing the grid you specified in the controller. Add columns, specifying the attribute as the field name in the database and the name as the text to appear in the header of the grid.

Customizing the order, filtering, search, and pagination is easy. Check out the Wice Grid GitHub page for instructions.

Wice Grid would be even better if it incorporated AJAX, to avoid page reloads when searching, for instance. However, that is the trade-off for its extremely quick setup.