Derivation_url fails with undefined method `derivation_url' for nil:NilClass

Using Shrine and have a weird issue where it seems it should work but does not. I am not sure how to troubleshoot.

featured_image and digital_content look the same and are both class ProductUploader::UploadedFile, however when I try to use digital_content it fails with undefined method `derivation_url’ for nil:NilClass
(The cache id is different since the file is uploaded at different times into another model)

featured_image

#<ProductUploader::UploadedFile storage=:cache id=“86db7d87c45f8231f0b93661780e9dc3.jpg” metadata={“filename”=>“rock-1_640.jpg”, “size”=>105380, “mime_type”=>“image/jpeg”, “width”=>640, “height”=>456}>

digital_content

<ProductUploader::UploadedFile storage=:cache id=“447a2bd3275f54932e0a3606c11aa958.jpg” metadata={“filename”=>“rock-1_640.jpg”, “size”=>105380, “mime_type”=>“image/jpeg”, “width”=>640, “height”=>456}>

WORKS

<%= image_tag @product.featured_image.derivation_url(:thumbnail, 348, 175).to_s %>

FAILS

<%= image_tag form.object.digital_content.derivation_url(:thumbnail, 348, 175).to_s %>

WITH
undefined method `derivation_url’ for nil:NilClass

Ok, we can take #derivation_url out of the equation, as the problem is that form.object.digital_content returned nil when you expected it to return an attached file.

Without more information, I can only conclude that digital_content is nil because there is no file attached (i.e. digital_content_data column is nil). So, I would recommend looking into that.

If you think there is a bug in Shrine, where it returns nil when a file has in fact been attached, then I would need you to post your Shrine setup, ideally in a minimal self-contained script that reproduces the problem.

Wow - quick response on Sat!

When I output without derivation_url it works.

featured_image <%= form.object.featured_image.inspect %>

#<ProductUploader::UploadedFile storage=:cache id=“86db7d87c45f8231f0b93661780e9dc3.jpg” metadata={“filename”=>“rock-1_640.jpg”, “size”=>105380, “mime_type”=>“image/jpeg”, “width”=>640, “height”=>456}>

digital_content <%= form.object.digital_content.inspect %>

<ProductUploader::UploadedFile storage=:cache id=“447a2bd3275f54932e0a3606c11aa958.jpg” metadata={“filename”=>“rock-1_640.jpg”, “size”=>105380, “mime_type”=>“image/jpeg”, “width”=>640, “height”=>456}>

So I believe the issue is that it is indeed returning a false nil.

Will try to replicate in a repo.

Found a workaround that may make identifying root cause esier.

I was calling derivation_url inside a partial (did not work)

Tried both

<%= render “layouts/shared/content_fields”, form: content %>

<%= render partial: “layouts/shared/content_fields”, locals: { content: content.object, form: content } %>

When I embedded the partial code directly in the form it worked.

Here is the partial code

<%= content_tag :div, class: "content-nested-fields", data: { new_content_record: form.object.new_record? } do %>

  <% unless form.object.digital_content.blank? %>
    <%= image_tag form.digital_content.derivation_url(:thumbnail, 300, 300).to_s, width: 150, class: "img-thumbnail mr-3" %>
  <% end %>

  <div class="form-group">
    <%= form.label :title %>
    <%= form.text_field :title, class: 'form-control' %>
    <%= form.label :description %>
    <%= form.text_area :description, class: 'form-control' %>
  </div>

  <p class="text-right"><%= link_to "Remove", "#", data: { action: "click->product-contents#remove_association" }, class: "text-danger" %></p>

  <div class="form-group">
    <!-- will be replaced by Uppy -->
    <%= form.label :digital_content, "Select content" %>
    <%= form.file_field :digital_content,
        multiple: true,
        accept: ContentUploader::ALLOWED_TYPES.join(","),
        data: {
          upload_server: upload_server,
        } %>
  </div>

  <%= form.hidden_field :_destroy %>

<% end %>