Chris Oliver


234,920 Experience
17 Lessons Completed
256 Questions Solved


Hey Pete, this usually happens from one of two things:

1. You're using a third party library (like for example) that isn't compatible with Turbolinks events by default. These usually require some tweaking in order to make compatible. It all depends on the library but there are usually ways to do it. You can google for that library + turbolinks and see if anyone else has made it work, or if you can tweak it yourself.

2. Sometimes it can just be a simple setup issue if your JS is running incorrectly. Maybe you need the jQuery.turbolinks adapter, or just to modify your code slightly to allow running on multiple pages.

It all kinda depends on your code and the issues you're experiencing. They can be kinda hard to track down so the easy solution is to turn off turbolinks for those links in the meantime if you can figure it out. I don't think there's anything wrong with that so you can figure it out later.

Heck yeah man! :D

Posted in GoRails speed

It took me a little while, but I did it!

Good news! Heroku is actually really easy now.

Just tested it this morning and it's super easy to setup:

The trick is that you _must_ use the route mounted version because Heroku apps only expose one port. Just make sure you have a Redis connection added, and you should be all set.

You can try out my example app here: http://actioncable-gorails.... (just make sure you're on http, not https.

I haven't yet, was hoping that the first release candidate would ship, but still waiting on that. I put these episodes out and then like the next week a bunch changed so I didn't want to be making too many immediately outdated episodes.

Posted in GoRails speed

The memoization one is definitely up this alley. One really good example use case (that I realized after recording that episode) was that when you want to sync records from an API, memoizing the results so you can save / update copies in your database is really helpful.

I'm going to do another episode talking about all the things I use on GoRails, but that's definitely one of the tactics.

Posted in Deployment Question

Feel free to post it here so other people can find it and the solution. Which version did you upgrade to? 3.4.0?

Posted in Deployment Question

The Rails version doesn't matter because the error is in Capistrano and there's a missing compatibility thing somewhere internally.

Posted in Deployment Question

You might want to update to the latest Capistrano.

Posted in How to add logo image to mailer

Ah cool. I've used in the past to do that, but then I just started paying $50/yr for Typekit and no longer have to deal with that for almost any fonts I could want to use.

Posted in How to add logo image to mailer

Oh fun, CORS is not a super fun thing to mess with. I'm not sure if you can do that with email, but you have to allow origins with CORS to determine where your fonts can be loaded from:

Posted in How to add logo image to mailer

You should just be able to use the regular old <%= image_tag("logo.png") %> helpers just like you would use in your views. You may need to set your asset_host so that it includes a full URL for the images in the emails since they aren't displayed in the browser under your domain.

# I believe these should do the trick:
config.action_controller.asset_host = 'http://localhost:3000'
config.action_mailer.asset_host = config.action_controller.asset_host

This looks like a fun project! If you've already got elasticsearch going, it'll do really well to handle the search queries (plus it should handle the ordering from closes to furthest as well). Curious to hear how it goes man!

I would probably use the Geocoder gem for this. You can back it with interchangeable APIs and cache results in Redis which is really handy.

Have you considered using the geosearch that's built into ElasticSearch? You can pass it in either a bounding box (like the coordinates of a Google Map embedded on the page like Yelp does if you drag the map), or you can search within a radius, so you can easily find things by km or miles away.

What's your UI going to look like for the interactions?

Templates are a definitely interesting topic. I spent some time making templates in the past and I believe I ended up trying a couple different things. One approach I had a templates table, but it felt like there was a lot of duplication going on (two tables, same columns for example). The other was to mark records as templates and we'd just copy a few fields over to the new record. That ended up working better for what we were doing because it was pretty simple.

I personally like just operating off an existing record because you can just say "Okay, let's dup this, including it's children, but only keep these certain fields, strip out these others" and you don't have to deal with creating multiple tables or anything.

If you go that approach, you can use the .dup method on the instance, so you'd load up the original and then call .dup on it which should generate a copy in memory without an ID attached. You might also need to loop through associated records and dup those as well for the new model. Then you can clean any of the fields you want by setting them to nil or whatever.

The other approach for this same thing is to take the attributes from the original, use except on the hash to strip out those fields, and then create a new record like you normally would in the controller. Either way is effectively the same, this one might be a lot more familiar to most people. .dup wins if you don't need to strip out any fields though because everything's already set automatically.

Posted in Memoization Discussion

Yes, great point! Thanks for mentioning that.

Posted in Subscriptions with Stripe Discussion

Double check that the authenticity token is being submitted in the params. Your screenshot looks like it isn't being included. It might be not making a POST request and just doing a normal GET, which isn't what you want.

Posted in Subscriptions with Stripe Discussion

You might double check that that file is getting required in your application.js. Sometimes that can be all that's missing. If it is, then add some print statements to see if your code is actually running, might be just something simple there.

Posted in About In-App Navbar Notifications

Bunch of different ways you could do this, but in most cases, you're going to want to base this off two things

  1. the class name of the notifiable (ForumPost, User, ForumThread, etc)
  2. the action that happened (commented, subscribed, asked, etc)

Most of the time each time one of these two things change, you'll want to render a different snippet of JSON.

The two main approaches I'd suggest are as follows:

1 -Use a case statement to break down the notifiable to the class and action, then return the proper url for it. You could define this stuff in helper methods.

case notification.notifiable
when ForumThread
  case notification.action
  when "created"
when User
  case notification.action
  when "subscribed"

This is pretty straightforward and really easy to customize the URLs. You can just adapt things easily, refactor this to methods with case statements if it gets too long and unwieldy, etc.

Of course, this breaks down when you need to start customizing the JSON more than just different URLs, so that's why option #2 might make more sense.

2 - Another way to do this is to render partials dynamically, but you have to make sure if you introduce a new notification type, you must make sure you create a template for it. This is what I generally do so that everything is nicely organized and easily customizable.

json.partial! "notifications/#{notification.notifiable.model_name.route_key}/#{notification.action}", notification: notification

For example, this would take a notification that's notifiable is a ForumThread and the action created and render the app/views/notifications/forum_threads/created.json.jbuilder template. In there you could define your details, like the different url, etc.

In most applications, notifications often end up needing more complex metadata for each one, so this is a case where it makes more sense to define each one's JSON individually. You can include different data structures where as in the first approach, it's much harder to.

It all really depends what you want to do, but I'd suggest starting with the first one, and refactoring into the second one as things progress if necessary.

Posted in Memoization Discussion

I hadn't seen this before, quite an interesting approach. I like the intentions / goals a lot and a good discussion about it. There's a certain elegance to it that feels very clean.

That said, I'm not sure memoization is really necessary for any of this. It might be useful in post_params, but it's one of those cases like name where it's ultra fast to run and only usually gets access once, so unlikely to provide any speed benefits to memoize.

For example, you can just use before_actions to accomplish the same result:

The benefit of instance variables is that it provides you a way at a glance to determine which variables you have access to in your views, plus they're automatically available as well without having to expose helper_methods.

And like the discussion mentioned, for the index methods they tend to have scopes applied often, so I usually find them useful to always be written in the method so you can easily find it, rather than having to look at helper methods or before_actions for that. It makes more sense for member actions where you've always got to set @post for example and it's kind of assumed that it'll always be the same.

What do you think?

logo Created with Sketch.

Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

© 2020 GoRails, LLC. All rights reserved.