Thomas M

Joined

510 Experience
2 Lessons Completed
0 Questions Solved

Activity

Hello,

We plan to upgrade a production app from Rails 3 to 5.2.
We basically plan to use a mirror app since the production app is untested.
Current app is using jquery, coffee and asset pipeline

My primary concern is focused on assets management. Since we target a rails 5 app we want to use ES6, webpacker and react, and want to get rid of coffee.

How can we plan this transition ? Can we use both webpacker and old pipeline (sprocket) the time of the transition, using both javascript_tag and javascript pack_tag ?

I have the same interrogation about the css assets.

Can someone point me good resources explaining how to transition from one to another assets management please ?

Thank you in advance :)

For information purpose, I find thoses articles from EvilMartian which are great resources understanding the new webpacker way :
Part 1 https://evilmartians.com/chronicles/evil-front-part-1
Part 2 https://evilmartians.com/chronicles/evil-front-part-2
Part 3 https://evilmartians.com/chronicles/evil-front-part-3

Kind regards,
Thom

Posted in Eager loading with Gem Mailboxer

Hello everyone,

I have a User model which act_as_messageable using the Mailboxer gem.
In my users#index view, I would like to add a link for each user to the first user conversation

Right now, I have my link which looks like this :
<%= link_to conversation_path(user.mailbox.conversations.first) do %>Button to conv<% end %>

It works but, since I didn't include the conversations when I requested the users, I see a lot of n+1 queries.
How can I load the conversations at the same time than the users ?

I already tried User.all.includes(mailbox: :conversations) with no luck

Thank you in advance for your help !
Kind Regards
Thomas

Posted in Colorbox & Turbolinks load

Hello,

Rails 5.1.0 & Turbolinks5 & Jquery3.1.2 here

I'm trying to make jQuery Colorbox works with dynamicly loaded elements (using ActionCable) with no luck.

With the implementation below, Colorbox is tied to a 'on click' event on the parent element, wich allows the newly loaded elements to be recognized automatically. However, this might not be the best option since colorbox seems to be ignored on all element when the user comes form another page (turbolinks:load), and is not available in console. Everything works fine on page reload.

What do I miss? Thank you in advance for your help

Here is my implementation:

class @GalleryLoader
  constructor: (@container,@elem) ->
    @setEvents()

  setEvents: ->
    $(@container).on 'click', @elem, @handleClick

  handleClick: (e) ->
    e.preventDefault()
    $(this).colorbox
      transition: 'fade'

$(document).on 'turbolinks:load', ->
  if (($ "[data-behavior='project-media-parent']").length)
    new GalleryLoader "[data-behavior='project-media-parent']", "[data-behavior='medium-link']"
    ```

Depending on the size of your user base, activity feeds can rapidly growing and become the slowest part of your app.
If your user base won't become massive, you can code it yourself, and Chris detailed a very good implementation.
A more robust alternative is https://github.com/ello/streams which is a wrapper around SoundCloud's Roshi.
A scalable and easy to implement solution is https://getstream.io/

Hope that helped you.

Posted in Group Chat with ActionCable: Part 4 Discussion

Hello Chris, just a quick question regarding the best practice with jobs: I learned in the past that passing only the id parameter to the job with sidekiq or else, then find the instance inside the job is the best practice. Since you pass the complete instance, I'm wondering if Rails do it for us automagically with ActiveJob? Thank you

Posted in Inviting Users with devise_invitable Discussion

Cool video and very clear explanations !
Maybe you can give me a hint on how you would deal with a not so different event management app I'm working on :
User manage its Collaborators like on its phone, meaning full control on Collaborator profiles, and add them to an Event. Two dedicated models are used since Collaborator isn't unique (many User can create a Collaborator which is the same person). The thing is a User is notified of each event with a Collaborator that share the same email, and can choose to take control of it (Collaborator become User). This is the only way I found to have a fully working app before all collaborators joined it as user. It works, but I'm kind of stuck when, on a project, I have to loop through User and Collaborator to show the Event team efficiently. Is there a good way to do this ? Thank you for your very helpful advices

Posted in Authorization with Pundit Discussion

Very useful episode. Two things came into my mind while watching it regarding the best practice using pundit combined with devise:

- Since pundit policy is checking for user presence, devise before_action :authenticate_user! seems redundant. Is it good practice to keep it or delete it ?

- Another thing that seems interesting with pundit is scope, which let you avoid dealing with query starting with current_user.something. I tend to use the User class directly (instead of the current_user) on my queries, it allows me to let the user owning the object (address, avatar) or the admin editing the data simply by navigating on the users#edit page (or registrations#edit if devise). Is it a good practice or there is a better way ? Thank you in advance for your lights.

Posted in CoffeeScript Class + Partial remotly reloaded + Binding

Hey, thank you for your answer.
I came to the same solution, using @ClassName or window.ClassName (and detailing the problem & solution in a forum post). Everything is working fine now :)

Posted in CoffeeScript Class + Partial remotly reloaded + Binding

I found my mistake : you have to declare your coffeeScript class globally to allow a call from js.

In case of someone encounters the same problem, I solved it like that :

assets/javascripts/myclassfile.coffee

  @ClassName (notice the @, you can use window.ClassName too)
    constructor: (elem) ->

views/users/destroy.js

  $("[data-behavior=image-profile-container]").html("<%= j render: 'your_partial' %>");
    new UploadFile($("[data-behavior='upload-image-user-avatar']"));

Posted in CoffeeScript Class + Partial remotly reloaded + Binding

Hi,

I'm currently rewriting my js file following the class encapsulation episode.
It works well but I'm struggling on with the binding/response for my image uploader.

My view contains a form with 4 file-fields, each for a specific image.
While uploading, a progress bar appears then a success message.
If a picture was already uploaded, a preview and a 'Remove' link appears.

When I click the remove link, image1#destroy is colled remotly and attachement is cleaned, a new one is built and the partial containing the file field is reloaded.
However, no matter what I try, I can't not figure how to make the new file field considered by the uploader, the consequence being that I lost my progress bar and preview.

Here is the relevant code :

users/update.html.erb

<%= form_for(resource, as: resource_name, method: :put, url: registration_path(resource_name),
html: { class: 'form-horizontal directUpload black', role: 'form', multipart: true,
data: { 'form-data' => (@s3_direct_post.fields), 'url' => @s3_direct_post.url }
}) do |f| %>

        <div data-behavior="image-profile-container">
          <%= render partial: "documents/vignette", locals: { resource: @user, attachment: @user.avatar } %>
        </div>

        <div data-behavior="image-logo-container">
          <%= render partial: "documents/vignette", locals: { resource: @user, attachment: @user.logo } %>
        </div>

...
... submit
<% end %>

documents/_vignette.html.erb

<%= fields_for resource do |r| %>
  <%= r.fields_for attachment.class.name.underscore.to_sym do |v| %>
    <%= v.file_field(:attachment, accept: "image/gif,image/png,image/jpg,image/jpeg", class: "vignette_file", data: { behavior: "upload-image-#{resource.class.name.underscore}-#{attachment.class.name.underscore}-#{attachment.id}" } ) %>
  <% end %>
<% end %>
<% if attachment && attachment.attachment_file_size != nil %>
  <%= link_to t("vignettes.delete"), { controller: "#{attachment.class.name.underscore.pluralize}", action: 'destroy', user_id: current_user }, { method: :delete, confirm: "Are you sure?", data: {confirm: "Are you sure?", behavior: "delete-image" }, remote: true } %>
  <%= t "vignettes.delete" %>
<% end %>

views/avatars/destroy.js

$("[data-behavior='image-profile-container']").html("<%= j render partial: 'documents/vignette', locals: { resource: @user, attachment: @user.profile } %>");
-- I tried to add new UploadImage() here

js/image_uploader.coffee

class UploadImage
  constructor: (elem) ->
    fileInput = $(elem)
    form = $(fileInput.parents("form:first"))
    submitButton = form.find 'input[type="submit"]'
    progressBar = $("<div class='bar'></div>")
...
$(document).on "page:change", ->
  $(".directUpload").find("input:file").each (i, elem) ->
    console.log "input is: " + elem
    new UploadImage(elem)

Everything seems to work, except that the new file field isn't considered by my uploader.
What is the best way to deal with the binding of a new element in the dom ?
I already tried live, ready, a[data-remote], to call UploadImage passing the elem, with no luck.
Thank you for your help

Great episode, the use of class is really interesting. I saw that you use a standard ajax request to change the todo status. I would have use a link to the same url with a "remote: true" to process this action. Would you mind explaining what is the rule of thumb regarding the use of the rails way VS the standard ajax is better ?.
Currently, I user remote true only when I have to reload a partial.
More contextual question : I have a user.attachment nested inside a user#update form. A delete link (using remote: true) proceed the @user.attachment.nil @user.attachment.save. Everything works as expected, but I'm wondering what is the best practice for reload this file field ? Since it's a nested form, I have to re-do a fields_for @user around the field_for attachment to avoid passing to the partial the "f" as a locals variable. It works, but doesn't look clean. Thank you in advance for your advice.

Posted in Refactoring with the Null Object Pattern Discussion

simply use def name(*) 'name'; end did the trick

Posted in Refactoring with the Null Object Pattern Discussion

Really cool video, the null object pattern is definitely a cleaner way than using :try.
I'm trying to use it in combination with the globalize gem, and get stuck when I want to force the locale. Per example, the standard use is article.title and when I want to force the language I do article.title(:en). In this particular case, if no article is found, MissingArticle.new method is called and generates a wrong number of arguments given (1 for 0) error. Do you have any hint on this ?

Posted in Sharing Data With Javascript Discussion

Thank you for this video, very interesting way of autoloading new notifications.

However, polling sounds a bit "old school". I read a lot about Active Live and websockets with the upcoming release of rails 5. Wouldn't it be interesting for this case to share new notifications automagically to all users concerned by them as soon as they are created ? Or maybe it's too heavy ?

Posted in Basic Authentication and RSS Feeds Discussion

Hey
May I ask how would you implement a simple authentication form (simple password field) to filter private pages, for private photo album/info/etc per say ?
Click the link -> form -> load password protected page if password is true.