Search code examples
ruby-on-railscocoon-gem

Rails and Cocoon. Accessing values from child model in Edit Form


I’m using Cocoon in a nested form where I have a model “Request” that can have many attachments (adjuntos), handled by Shrine.

The same form partial is being used both to Create and Edit the requests, and although the functionality is working fine and I am being able to upload the files and successfully update the models, I have a problem with the information shown for the Edit action.

The thing is that it is being rendered one input per each file currently attached to Request as expected and I can edit the attachment by selecting a new one or delete it, but I’m being unable to show the name of the file corresponding to each of these inputs, so the user won’t be able to know which of the attachments is editing. Apparently I can't use the object 'f' in _adjunto_fields.html.erb to access the values of the children model.

this input corresponds to a currently attached file to this model

_form.html.erb

<%= form_for @request do |f| %> 
<%= render 'shared/errors', object: @request %>
  <div>
    <%= f.label :ot %>
    <%= f.text_field :ot%>
  </div>
  <div>
    <%= f.label :area %>
    <%= f.text_field :area%>
  </div>
  <div>
    <%= f.label :titulo %>
    <%= f.text_field :titulo%>
  </div>
  <div>
    <%= f.label :observaciones %>
    <%= f.text_field :observaciones%>
  </div>
  <div>
    <%= f.label :prioridad %>
    <%= f.text_field :prioridad%>
  </div>

  <div id="adjuntos">
    <%= f.fields_for :adjuntos do |adjunto| %>
    <%= render 'adjunto_fields', f: adjunto %>
  <%end%>

  <div class="links">
    <%= link_to_add_association 'añadir adjunto', f , :adjuntos %>
  </div>
  </div>

  <%= f.submit %>
  <%end%>

_adjuntos_fields.html.erb

 <div class="nested-fields">
   <%= f.label :adjunto %>
   <%= f.file_field :adjunto%>

   <%= f.check_box :_destroy%>

   <%= link_to_remove_association "quitar adjunto", f %>
 </div>

Edit: Trying to access f.object in the form I get an error because f.object is nil:

<div class="nested-fields">
  <%= f.label :adjunto %>
  <%= f.file_field :adjunto%>
  <%#<%raise 'foo'%>
  <% parsed_data = JSON.parse f.object.adjunto_data %>
  <%= parsed_data["metadata"]["filename"]%>

  <%= f.check_box :_destroy%>

  <%= link_to_remove_association "quitar adjunto", f %>
</div>

>> f.object => #<Adjunto id: nil, title: nil, adjunto_data: nil, created_at: nil, updated_at: nil, request_id: 1>

But If I just uncomment raise 'error' debug mode I can actually access f.object from the console:

>> f.object => #<Adjunto id: 4, title: nil, adjunto_data: "{\"id\":\"4cbf9b5477c586779069a5144cd67104.PNG\",\"stor...", created_at: "2017-09-26 20:49:47", updated_at: "2017-09-26 20:49:47", request_id: 1>

Edit2. Calling the object outside from the _adjunto_fields form works:

<div id="adjuntos">
  <%= f.fields_for :adjuntos do |adjunto| %>
    <%= render 'adjunto_fields', f: adjunto %>
    <% parsed_data = JSON.parse adjunto.object.adjunto_data %>
    <%=parsed_data["metadata"]["filename"]%>
  <%end%>

  <div class="links">
    <%= link_to_add_association 'añadir adjunto', f , :adjuntos %>
  </div>

</div>

Solution

  • I'm not 100% sure how the object is being passed from the fields_for loop into the partial, but you should be able to access the adjunto object outside of the partial with ajunto.object, so you could add a line in _form.html.erb after rendering the partial (but still within the fields_for loop) to display the filename.