Skip to main content

Blog

Looking for old posts? Visit the archive.

Announcing New Features And Subscriptions Plans

With the holiday season just beginning, I'm proud to announce that GoRails gets a fresh coat of paint and a bunch of new features to make learning Ruby on Rails that much better. 🎉

Here's some of the awesome new stuff you can check out right now:

New feature: Series


GoRails Series

I'm now organizing videos in Series so you can dive deep into specific topics. After publishing over 150 different episodes, there's a lot of content on GoRails and it can be hard to dive into higher level topics, so that's what Series are here to solve. I've already grouped some of the existing episodes into series for easier watching, and I'll be releasing brand new series on APIs, Testing, React, Vue, and more coming very, very soon.

Keep an eye on the GoRails Series page for new releases!

New Feature: Watch Later

Watch Later

When you're browsing GoRails, sometimes a few episodes catch your eye and you want to make sure to mark those down to watch later. Now you can! Hit the "Watch Later" button and the episodes will be added to your queue on your Dashboard.

New Feature: Mark as Complete

Mark as complete

It's hard to keep track of which episodes you've watched and which you haven't, so I've added the ability for you to mark episodes as complete.

Upgraded: Forums


GoRails forums

The forums have been a fantastic place to ask questions and get answers. Like Github, I've added the ability to add reactions to posts so you can easily add your thoughts to a conversation.

I've also added subscriber badges and reactions to the forum. You earn a new badge for each milestone you reach of 1, 3, 6, 12, and 24 months.

New Subscription Plans

Along with all the new features, I'm updating our pricing. I'll be investing everything back into GoRails to expand the topics into more things like Vue.js, iOS / Android with Rails backends, testing, and more. I'm also planning on expanding our community and improving support to make GoRails an even better place to get advice on how to build great web apps.

GoRails will be going up to $19/mo for all new subscribers. As a subscriber, you'll get access to all lessons on GoRails and support the subscribers-only forum and private Slack group.

If you haven't subscribed yet, GoRails is on sale for $9/mo up until Cyber Monday (November 28, 2016). Be sure to subscribe to get the discount before it ends!

If you're currently subscribed to GoRails, don't worry! You'll be grandfathered in to your current plan as long as you're subscribed. That's my way of saying thanks for all the support you've given me over the years. 💕

Thank you

Almost 3 years ago I started working on GoRails fulltime. Today, there are over 10,000 people using GoRails. It's come an amazing way because of you. Thanks to your feedback, requests, and questions I've been able to make GoRails a much more useful resource for learning Ruby on Rails.

I believe you should be able to build any web app you can imagine, and have the resources to look up how to implement the features you'll need for it. We've accomplished some of this together but have a lot more to do. These changes are a big step in the direction of helping anyone become an incredibly good developer and I hope you're as excited about the future as I am! As always, I'm excited to hear your feedback.

yay

Continue reading →

Using Named Scopes Across Models with ActiveRecord#Merge

 
wistiaEmbed = Wistia.embed("oy1d6l4h3y", { videoFoam: true });


After years of working with ActiveRecord and watching it change so much, it is exciting to find new features you didn't know about. The one I discovered this week is ActiveRecord#merge. It is one of the most underused methods in ActiveRecord, due in part, to the name. It isn't necessarily clear what they mean by "merge" but it's simply a way of using a named scope on a joined model.

Say we have two models that are associated and one of them has a scope:

class Author < ActiveRecord::Base
  has_many :books
end
class Book < ActiveRecord::Base
  belongs_to :author

  scope :available, ->{ where(available: true) }
end

Let's say we want to join the tables to find all Authors who have books that are available. Without ActiveRecord#merge, we have to make this query:

Author.joins(:books).where("books.available = ?", true)
SELECT "authors".* FROM "authors" INNER JOIN "books" ON "books"."author_id" = "authors"."id" WHERE "books"."available" = 't'

But with ActiveRecord#merge, this becomes a whole lot cleaner and we don't duplicate the available scope:

Author.joins(:books).merge(Book.available)
SELECT "authors".* FROM "authors" INNER JOIN "books" ON "books"."author_id" = "authors"."id" WHERE "books"."available" = 't'

As you can see, the resulting SQL queries are exactly the same. ActiveRecord#merge is a great way to reduce the duplication in your code to continue relying on the named scopes you define in your models. I really want to see more people using this so please share this around!

Want to learn more about Rails and become a great programmer?

Check out the Ruby on Rails Screencasts for more awesome learning material like this.

Continue reading →

SimpleCalendar 1.1 released!

Having spent a significant time over the years playing with various calendar gems, I felt they were all lacking in different ways. Some were overbearing providing you CSS stylesheets when all I wanted was a plain calendar. Others were a bit too involved, there was a lot of work on my end and all I wanted to do was render a simple table for the calendar.

Calendars also aren't necessarily a month anyways. Sometimes you want to see 6 weeks at a time. Sometimes 2 weeks. Sometimes you only want 4 days. But none of the gems seemed to care.

Seeing all this, I decided to make my own: github.com/excid3/simple_calendar

At the simplest version, simple_calendar renders a table for your calendar.

You can make a month calendar:

<%= month_calendar do |date| %>
<%= date %>
<% end %>

You can make a 2 week calendar:

<%= week_calendar number_of_weeks: 2 do |date| %>
<%= date %>
<% end %>

You can make a 4 day agenda calendar:

<%= calendar number_of_days: 4 do |date| %>
<%= date %>
<% end %>

The calendar just generates some basic HTML for you that you are free to work with, complete with navigation links and a header (if you want it).

<div>
  <a href="/events?start_date=2014-05-13">«</a>
  <a href="/events?start_date=2014-05-18">»</a>
</div>
<table class="table table-bordered">
  <tbody>
    <tr>
      <td class="day today current-month wday-3" current="2014-05-14" start="2014-05-14">
        2014-05-14
      </td>
      <td class="day future current-month wday-4" current="2014-05-15" start="2014-05-14">
        2014-05-15
      </td>
      <td class="day future current-month wday-5" current="2014-05-16" start="2014-05-14">
        2014-05-16
      </td>
      <td class="day future current-month wday-6" current="2014-05-17" start="2014-05-14">
        2014-05-17
      </td>
    </tr>
  </tbody>
</table>

These are fine and dandy, but what is a calendar without events? We've got that too.

Because we need to know what attribute on your model is the event's start time, we have a simple include in your model that lets you define it:

class Event < ActiveRecord::Base
extend SimpleCalendar
has_calendar attribute: :start_time
end

You define which attribute to use in your model and then simply pass them into your view to have them all sorted out by day.

<%= month_calendar events: Event.all do |date, events| %>
<%= date %>
<% events.each do |event %>
<div><%= event.name %></div>
<% end %>
<% end %>

This will yield the date and all the events sorted by start time for the given date to your code. Do with them however you please, it is up to you.

I'm pleased with the end result currently and look forward to improving it more in the future. If you have any suggestions or improvements to make, make a Github issue and let's make the easiest calendar for Rails we can!

Try it out at https://github.com/excid3/simple_calendar

Continue reading →

Why You Should Focus On Writing Code With Clarity

As you know, writing code goes far deeper than you probably expected when you first started. Programming is a form of expression, like writing a novel. The better you are able to express your intentions, the better your code will be.

Other people (including yourself six months from now) have to interpret what you were thinking when they go to fix a bug in your application. They have to get familiar with your thought process to figure out how to not only update your code but make sure they don't break it.

That's why clarity in programming is so important. It is a way for you to express your intentions of what you want to accomplish. We are defining a set of rules on how interactions with software should work.

The definition of clarity is this:

clearness or lucidity as to perception or understanding; freedom from indistinctness or ambiguity.

I think the last part is the impost important: Freedom from indistinctness or ambiguity.

Think about this in terms of code. When was the last time you looked at a piece of logic thinking "What in the hell is this doing?" The reason you ask yourself that is because there is too much ambiguity. There is no obvious path for the code to take.

If statements are a great example. Every time you read an "if" you must think okay, assuming this is true then this happens. If it isn't true, other things happen. What are those other things? What triggers them? What defines this behavior? Why can't I hold all these limes?

When your revisit a project like this, you have to step inside someone else's mind for a while to be able to understand what is going on. If the code is written very clearly, you will be able to jump into their mindset with ease and begin making changes. If it is unclear, it could take you days or weeks to figure out.

Clarity is one of the reasons why Ruby has become so popular as a language.

It provides you with immense flexibility on how it can be written with the purpose of providing understanding to the developers.

Rails is a great example of this. It is nothing more than a set of tools and helpers that allow you to write web applications with a certain level of clarity. If a programmer is generally familiar with ActiveRecord, they will have no trouble interacting with the database. Want to create a new User record? Just call User.create. The User.create method is so clear that it is hard to imagine a better way of expressing this in code.

Even the folder structure provides some clarity and insight into an application. Someone with experience in the Model-View-Controller pattern will be able to get a general idea of how your application works by just looking at the files and folders in your project. Compare this to a project without any organization. You've probably created an app in your early days as a programmer that was just a complete mess.

This even extends far down into the smaller details of Rails. When you want to make a word plural based upon a number, you can just call pluralize. No need for if statements or keeping track of English rules on pluralization. It's already there for you. The pluralize method works exactly how you would expect. A quick glance at the name of the method and you know what it does. Seeing this used in an application provides instant clarity to the programmer who is reading the code.

Write the code you want to have

In Test Driven Development, you often start by writing the code you want to have. You define the clearest written code first and then you go implement it. This way you start with a clarity-first approach as you try to maximize the amount of understanding conveyed in the way your code is written.

You think "I'd really like to check if the user is signed in".

So what should you do? You define a method called user_signed_in? that returns true or false. This means you can use if user_signed_in? to check if the user is signed in your code and provide the intent of your code with the utmost clarity.

The huge benefit here is that Ruby allows you to add a question mark at the end of your method names. Everyone knows what the return value of this method is without thinking about it.

So clarity in writing new code is important because it helps simplify things in the future. But what are we going to do with that code in the future? Maintenance. Fixing bugs. Changing behaviors. Adding new features.

Maintenance is 70% of writing software.

When you think about this, that's a huge amount of time. The code you write today is going to significantly affect the time spent in the future. Poorly written code today can mean months of development later. But clearly written code today can also mean merely minutes or hours of maintenance in the future.

This means (assuming you stick with a project) you can choose to invest your time either now or in the future. Which is the logical place to invest in? Which approach will save your company or clients more money? Which approach will make you happier in the long run?

The best programmers tend to be the ones who care about clarity.

Continue reading →

How To Create Invitations From Any Model with Devise Invitable

A really useful extenison to the Devise authentication gem is devise_invitable. It adds invitation functionality that can be used for building a referral system or just general email invitations to your web app.

The way it is works is extremely simple. It just adds a invite! method to the model and you can pass in attributes just like calling create.

User.invite!(email: "new_user@example.com", name: "John Doe")

This is great, and it automatically keeps track of which user sent the invitation if you pass that object in:

User.invite!({:email => "new_user@example.com"}, current_user)
# current_user will be set as invited_by

This is great for keeping track of who invited who, but this also requires the Inviter to have a few methods. These methods are basic helpers that devise_invitable has for extra configuration options like limiting the number of invitations a user can send out.

What happens when you want to invite a user from a different model that isn't devise_invitable though? It breaks!

Let's take this for example: We have AdminUsers which we definitely don't want created by invitations but we want them to be able to invite Users and track that an AdminUser invited them.

If you try this without adding devise_invitable to AdminUser, you'll get an error similar to these two errors: undefined methodhas_invitations_left?' for #AdminUser:0x102e98948andNameError (undefined local variable or method invitation_token' for #<AdminUser:0x0000010334baa8>):

The AdminUser model doesn't have the fields that devise_invitable requires so it crashes.

The fix is simple. We can include a module on the models that are inviting Users without adding devise_invitable:

class AdminUser < ActiveRecord::Base
  include DeviseInvitable::Inviter
end

Continue reading →