4

A similar question has already been asked, but the answer is only for Rails 3, so I am taking the liberty of asking a new question.

I have a Rails 4 app, with the following models:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
  has_many: :posts
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

class Post < ActiveRecord::Base
  belongs_to :calendar
end

The Post model has the following attributes:

references :calendar, index: true, foreign_key: true
date :date
time :time
string :subject
string :format
text :copy
attachment :image

and the attachment was setup as follows with Paperclip in Post model:

has_attached_file :image, styles: { small: "64x64", med: "100x100", large: "200x200" }
validates_attachment :image, :content_type => { :content_type => "image/png" },
                                :size => { :in => 0..3000.kilobytes }

Adding an image to a Post is working fine, through the following form:

<%= form_for [@calendar, @calendar.posts.build] do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <p>
      <%= f.label :date %><br>
      <%= f.date_select :date %>
    </p>
    <p>
      <%= f.label :time %><br>
      <%= f.time_select :time %>
    </p>
    <p>
      <%= f.label :subject %><br>
      <%= f.text_field :subject %>
    </p>
    <p>
      <%= f.label :format %><br>
      <%= f.text_field :format %>
    </p>
    <p>
      <%= f.label :copy %><br>
      <%= f.text_area :copy %>
    </p>
    <p>
      <%= f.label :image %><br>
      <%= f.file_field :image %>
    </p>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Viewing the image attached to a Post is also working well, thanks to this show view:

<h2>Post from <%= @post.date.strftime("%A, %d") %></h2>

<div>
    <p><strong>Date</strong></p>
    <%= @post.date.strftime("%A, %d") %>
</div>
<div>
    <p><strong>Time</strong></p>
    <%= @post.time.strftime("%I:%M %p") %>
</div>
<div>
    <p><strong>Subject</strong></p>
    <%= @post.subject %>
    </div>
<div>
    <p><strong>Format</strong></p>
    <%= @post.format %>
    </div>
<div>
    <p><strong>Copy</strong></p>
    <%= @post.copy %>
</div>
<div>
    <p><strong>Image</strong></p>
    <%= image_tag @post.image.url(:med) %>
</div>

However, when I go to the edit view, for a post where I have previously uploaded an image, I only see the field that allows me to add an image and a message saying "no file chosen".

The edit view uses (for now) the same form as the new view, as shown above.

How can I achieve the following:

  1. Have the uploaded image appear in the edit page.
  2. Allow users to delete this image.
  3. Allow users to replace this image with a new one.

–––––

UPDATE: I found a way to solve item #1 above, by replacing

<p>
  <%= f.label :image %><br>
  <%= f.file_field :image %>
</p>

with

<p>
  <%= f.label :image %><br>
    <% if @post.image.exists? %>
      <%= image_tag @post.image.url(:med) %>
    <% else %>
      <%= f.file_field :image %>
    <% end %>
</p>

in my Post edit view.

I am still working on items #2 & #3 and could definitely use some help with these.

–––––

I am happy to share more code if necessary.

Any idea?

Community
  • 1
  • 1
Thibaud Clement
  • 6,607
  • 10
  • 50
  • 103

1 Answers1

2

For #2 - Allow user to delete image, you might find this SO Issue helpful

OR, as per Paperclip's documentation you could simply create a dummy checkbox and, in the update method of your controller, look if the checkbox has been ticked and delete the attachment as mentioned in the documentation.

For #3 - Allow users to replace this image with a new one

Simply rework your code as follow:

<p>
  <%= f.label :image %><br>
    <% if @post.image.exists? %>
      <%= image_tag @post.image.url(:med) %>
    <% end %>
    <%= f.file_field :image %>
</p>

This way, the file_field is always present (allowing user to replace or add their image)

Community
  • 1
  • 1
Alexandre Voyer
  • 809
  • 6
  • 11
  • Merci beaucoup Alexandre. For #3, things work like a charm with your code. However, for #2, I am not sure how I should implement this. I will keep digging and update the question if necessary. – Thibaud Clement Oct 02 '15 at 18:14
  • 1
    Ca me fait plaisir! I'll edit my answer with an alternate way. – Alexandre Voyer Oct 02 '15 at 18:22
  • Parfait. I understand the idea behind creating a checkbox. I would rather have a small "x" button where user click and the image disappear, even if it is not deleted right away (and only deleted when the post is saved). That would require some JS, right? – Thibaud Clement Oct 02 '15 at 18:27
  • 1
    You could always create a route that calls a delete_image function in your post_controller and have a link_to that does an ajax call to that route and do some nifty javascript goodness once it's executed. – Alexandre Voyer Oct 02 '15 at 18:31
  • Awesome, thanks a lot for everything. Bonne journée à Gatineau (I lived in Ottawa for a year). – Thibaud Clement Oct 02 '15 at 18:33
  • Ca me fait plaisir! :) – Alexandre Voyer Oct 02 '15 at 18:34