TL

Joined

1,440 Experience
6 Lessons Completed
0 Questions Solved

Activity

Hi Chris, great video! One suggestion: I think the canonical way of accessing helpers in controllers is now helpers.<helper>, instead of view_context.x, because the latter instantiates a new view context on every call, so it's less performant.

Posted in Webpack Bundle Analyzer Discussion

Cant wait for the split chunks episode!

Posted in Ruby Module Include Tracking Discussion

Very nice that you showed how to make it work with Concerns.

Posted in Episode on GraphQL

Hi Chris,

Do you have any plans for an episode on Rails + GraphQL ?

I'd love to see your take on it, and see what exactly we're missing :)

Chris, hoping for the episode on using a CDN with user uploaded content, we use CarrierWave (and plan to keep using because it's years beyond ActiveStorage in features) and that's the biggest number of assets (and the heaviest assets) we have to serve.

AND a future episode :)

That's a feature to be added to Hatchbox :)

Posted in Should i be using jbuilder or AMS

I also would love to know what would be the Rails way of generating json. I like AMS but it looks like it's going away and jbuilder is bundled with new Rails apps per default.

We're using Rails and Webpacker with Vue single file components.

How do we insert images inside the <template> ? A far as I can see there are many options.

OPTION 1:
Use .vue.erb (with webpacker erb loader), and <% helpers.image_path %> as suggested in the official docs here.

Drawbacks: very slow to webpack compile for some reason (like 30 seconds on every single file change), AND it also breaks the linter. Also, still depends on Sprockets.

OPTION 2:
Add 'app/assets' to webpacker.yml resolved_paths array, as suggested in the official docs here, and then import the images directly in Javascript like the docs suggest:

import 'images/rails.png'

Drawbacks: to use this with Vue single file components, you kinda have to add it to the data or computed attributes, making them reactive. It's verbose, like so:

<template>
<img v-bind:src="railsImage">
</template>

<script>

import railsImage from 'images/rails.png';

export default {
  data() {
    return {
          railsImage,
    }
  }
}

OPTION 3:
Use require


<template>
  <img v-bind:src="require('images/rails.png')"
</template>

We can point to images/rails.png directly only if we add app/assets to the resolved_paths, otherwise you'll need to require ../../../app/assets/...

I thought this solution wouldn't use asset fingerprinting (the hash at the end of filename to help with cache invalidation), because it would be bringing the asset from Sprockets, but Webpacker does it automatically, creating a path like /packs/_/assets/images/rails-27695e0730a7fbf593ffbf5d8749024b.png

OPTION 4:
Our layman solution, which we use for some time in production for all 'staticData' I want to pass from Rails to Vue, using data-attributes. I use it not only for asset_paths, but for all data that is request-dependent (for example, my Rails app has internationalizaiton, so routes are dependent on request locale, that's why I can't use .erb in the javascript files for routes).

It works something like this. In the view:

<%= content_tag :div,
  nil,
  id: 'app_mount_point',
  'v-cloak': true,
  data: {
    'static-data': {
      railsImage: image_path('images/rails.png'),
            posts_path: posts_path,
    }
  }
%>

In the vue.app:


<template>
<img v-bind:src="staticData.railsImage">
<a v-bind:href="staticData.posts_path">See your posts in your language</a>
</template>
(...)
computed: {

    staticData() {
      return $(this.$root.$el).data('static-data');
    },

  },

This works great because staticData is a computed methods, which will be cached by Vue at load and wont be observed for changes unnecessarly.

It also helps that image_optim gem compresses all my asset images through Sprockets, so referencing them this way ensures I'm getting the compressed-processed image.

What option are you guys using? What would be the most idiomatic way of doing this?

Chris, isn't it important to include the following line in the main entry pack:

import "babel-polyfill";

Without it, as far as I understand, Babel will not transpile the ES6 code and there should be issues with current browsers, right?

Chris, could you add to the video description what exactly you go throufg in this video? since its a 30+ minute it would be nice to have a summary or index!

Posted in Looking for Rails work? / Hiring Rails developers?

SEEKING MID to SENIOR LEVEL RAILS DEVELOPER for profitable, 7-years in the running startup
Location: remote! (we're in Brazil, but you can work from your confy home :)
Fulltime or parttime (at least 4 hours/day if part time)
We are on Rails 5.2 and Ruby 2.5.3 :)
Please send your resume and desired wage to [email protected]. Looking forward to talking to you!

Posted in User Avatars with ActiveStorage Discussion

Hi Chris, is there any episode (or can you plan one!) that demonstrates how to have a javascript editor so the user can 'center' the crop of the avatar? In real world cases, the users will never upload a 'perfect' avatar to be used with a circle, it will generally be off-center, so solutions like CSS object-fit: cover; don't end up with a perfectly centered image.

Posted in Server Administration with Cockpit Discussion

Funny thing is, even tough I had NET::ERR_CERT_AUTHORITY_INVALID errors, I could accesss it with Chrome; now, after closing the window and trying again, I'm getting a HSTS message telling me that I can't override the invalid certificate and go through.

Posted in Server Administration with Cockpit Discussion

Chris, I get a not secure warning in Chrome when I try to access :9090 in my domain (I deploy with Hatchbox). It's sending the browser a self signed localhost certificate.

Let's say that I want to sanitize user generated HTML written by CKEDITOR or something similar.

CKEDITOR has a really nice hash-like syntax for allowing content:

config.allowedContent = {
    a: {
      attributes: 'href'
    },
    b: true,
    i: true,
    u: true,
    table: true,
    tbody: true,
    tr: true,
    td: true,
    blockquote: true,
    img: {
      attributes: [ '!src', 'alt', 'width', 'height' ],
      classes: [ 'align-left', 'align-center', 'align-right' ],
    },
    h1: true,
    h2: true,
    h3: true,
    ul: true,
    li: true,
    ol: true,
    figure: true,
    figcaption: true,
  };

It works like this:

  • only tags in the list are allowed;
  • if tag value is true, all attributes and classes are allowed for that html tag; otherwise, you can pass an object specifying which classes and attributes you want to allow for that specific tag.

I basically want to replicate that in the backend with Rails HTML Sanitizer.

What I currently have is a simple PermitScrubber:

class BlogPostScrubber < Rails::Html::PermitScrubber

  def initialize

    super

    self.tags = %w(
      p
      a
      b
      i
      u
      table
      tbody
      tr
      td
      blockquote
      img
      h1
      h2
      h3
      ul
      li
      ol
      figure
      figcaption
    )

  end

end

The problem is: if I specify @attributes in the PermitScrubber, it will allow those attributes for any element; also, I have no idea how to permit only specific CSS classes for certain tags.

Can anyone shed some light on a way to achieve this?

Posted in Video request: using message_bus gem

Message_bus is a really nice gem by Sam Saffron that powers Discourse and thousands of other sites; it offers a server-to-server channel based notification system (so, as far as I understand, your app can subscribe and notify itself of events, in an asynchronous way) and, the main feature for me, it provides for a real-time way of sending data to the front-end using polling, long-polling or long-polling + streaming, without having to configure Websockets, working out of the box with normal app servers like Puma and without having a huge performance impact.

It's also smart enough to share updates via multiple tabs so they don't all hit your app if you have multiple of them opened.

The gem is really powerfull and simple, but the documentation is lacking, so that's why I think it's a great candidate for a video by GoRails!

It could be used, for instance, to update comments our notifications in real time in the frontend.

I'm imagining a video where MessageBus is used to get updated JSON to the front-end, automatically feeding it into Vue or React!

Posted in How do I implement nested comments

I'm looking for a tutorial on how to implement nested comments in my project. The requirements are that the comments must be editable and deletable by owner as well. As a plus, we plan on using `act_as_votable` to make them votable, and have [+] and [-] signs to make them collapsible.

I was thinking in using Vue.js for this, since having a lot of comments and nested comments would implicate in having hundreds of unnecessary Rails forms (if we used plain Rails for that). 

Anyone know of a good tutorial on how to achieve this? If not, Chris, can you consider this as an episode request?
I'm using Rails 5.2.0 and Webpacker gem to deploy a Vue application.

The show.html.erb file is very simple:

<div data-behavior="vue-app"><MyComponent></MyComponent></div>

And then in my entry pack, packs/my_vue_app.js:

    import TurbolinksAdapter from 'vue-turbolinks';
    import Vue from 'vue/dist/vue.esm'
    Vue.use(TurbolinksAdapter);
    import MyComponent from '../components/my_app/index.vue'
    
    document.addEventListener('turbolinks:load', () => {
      
      var element = $('[data-behavior="vue-app"]');
    
      if(!element) { return };
    
      console.log('Initializing Vue');
    
      const app = new Vue({
        el: element[0],
        data: {
          
        },
        components: { MyComponent }
      })
    })

In development, everything works absolutely fine. The app is mounted and functional.

But in production, after the page load and JS runs, `<div data-behavior="vue-app">` is removed from the paging, leaving only `<!-- -->` in it's place.

In the console, there are absolutely no errors. I can confirm using DevTools that the pack js file is loaded, and it was parsed, since the console.log is printed in the console.

Heck, the proof that Vue is working is that the entire `<div>` where it was mounted was removed from DOM after JS parsing. 

The weirdest thing of all is that I could get the app to mount ONCE, by attaching a debugger on the console.log line and turning it off while the debugger paused execution. Even tough I saw the app mounting that time, I could not get it to mount later on, even fiddling with the debugger again ... it's really, really weird. 

These are the versions of package.json:

```
"vue": "^2.5.16",
"vue-loader": "14.2.2",
"vue-template-compiler": "^2.5.16",
```

The Rails app is brand new, with no config other than the default.

Webpacker gem is 3.5.3 and Rails is 5.2.0. 

After spending a really long time on this, I only found this github issue: https://github.com/rails/webpacker/issues/1520

I'm providing a link to the real, production app where this bug is happening: https://planilha.tramitacaointeligente.com.br/planilhas/ED2sUXz32-R9CJKdkmtf8Q

You'll see it's not mounting. Here's the same page in development:

[![screenshot of app mounted][1]][1]


  [1]: https://i.stack.imgur.com/ZZbk0.png
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.