[Ruby on Rails] Post image preview function in refile

Target

img_prev.gif

Development environment

ruby 2.5.7 Rails 5.2.4.3 OS: macOS Catalina

Premise

-Build login environment with devise -Posting function that only logged-in users can do

We will assume that the posting function has already been created.

flow

1 Introduction of gem refile Add 2 columns 3 Edit model 4 Editing controller 5 Edit view

Introduction of gem refile

Gemfile


gem 'refile', require: 'refile/rails', github: 'refile/refile'
Supplement refile is a gem that allows you to upload files.

Terminal


$ bundle install

Add column

Terminal


$ rails g migration AddPostImageIdToPosts post_image_id:string

Terminal


$ rails db:migrate

It is OK if t.string "post_image_id" is added.

db/schema


  create_table "posts", force: :cascade do |t|
    t.integer "user_id"
    t.string "title"
    t.string "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "post_image_id" # <--OK with this
    t.index ["user_id"], name: "index_posts_on_user_id"
  end

Edit model

app/models/post.rb


attachment :post_image
Supplement [Rules for using refile] 1 Image upload is implemented with <% = f.attachment_field: image%> 2 Add the method "attachment" for uploading the image to the model and specify the image. * Since post_image_id was added this time, specify post_image.

Editing controller

You can also change the post_image by adding the following.

app/controllers/posts_controller.rb


  def post_params
    params.require(:post).permit(:title, :body, :post_image)
  end

edit view

This time, to display the default image first, I prepared an image file called no-image.png in advance. The save location will be in app / assets / images.

erb:app/views/posts/new.html.erb



<% form_with,...%>
...

  <div>
    <%= attachment_image_tag @post, :post_image, fallback: "no-image.png ", id: "img_prev", style: "height: 250px; width:300px;" %><br>
    <%= f.attachment_field :post_image %>
  </div>

...

<% end %>

...

<script>
$(document).on("turbolinks:load", function(){
  function readURL(input) {
    if(input.files && input.files[0]){
      var reader = new FileReader();
      reader.onload = function (e) {
        $('#img_prev').attr('src', e.target.result);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }
  $("#post_post_image").change(function(){
    readURL(this);
  });
});
</script>

Supplement [attachment_image_tag] Create an img tag with the helper method provided by refile.
Supplement [fallback] Specify the image to be displayed when something goes wrong.
Supplement [turbolinks: load] Set to work with first load, reload, and page switching.
Supplement [About Javascript operation] Manipulate the attribute of id = img_prev, Change the loading URL of post_img of post model with change method
Supplement [If Runtime Error is displayed] On the code of the error screen

Refile.secret_key = ...


 Is displayed.
 Copy the line containing that Refile.secret_key = and
 In config / initializers / application_controller_renderer.rb
 You can eliminate the error by adding it at the bottom.
</details>


Recommended Posts