Browse Source

Add profile pictures

Frans Bergman 7 years ago
parent
commit
a2e881c570

+ 3 - 0
.gitignore

@@ -21,3 +21,6 @@
 /yarn-error.log
 
 .byebug_history
+
+# Ignore uploaded test images.
+/public/uploads

+ 4 - 0
Gemfile

@@ -39,6 +39,10 @@ gem 'bootstrap_form', '~> 2.7.0'
 gem 'bcrypt', '~> 3.1.7'
 # Use faker to generate seed data
 gem 'faker', '~> 1.7.3'
+# CarrierWave for image uploading
+gem 'carrierwave',             '1.1.0'
+# MiniMagick for image resizing
+gem 'mini_magick',             '4.7.0'
 
 # Use Capistrano for deployment
 # gem 'capistrano-rails', group: :development

+ 10 - 0
Gemfile.lock

@@ -58,6 +58,10 @@ GEM
       rack (>= 1.0.0)
       rack-test (>= 0.5.4)
       xpath (~> 2.0)
+    carrierwave (1.1.0)
+      activemodel (>= 4.0.0)
+      activesupport (>= 4.0.0)
+      mime-types (>= 1.16)
     childprocess (0.8.0)
       ffi (~> 1.0, >= 1.0.11)
     coffee-rails (4.2.2)
@@ -97,6 +101,10 @@ GEM
     mail (2.7.0)
       mini_mime (>= 0.1.1)
     method_source (0.9.0)
+    mime-types (3.1)
+      mime-types-data (~> 3.2015)
+    mime-types-data (3.2016.0521)
+    mini_magick (4.7.0)
     mini_mime (1.0.0)
     mini_portile2 (2.3.0)
     minitest (5.10.3)
@@ -199,12 +207,14 @@ DEPENDENCIES
   bootstrap_form (~> 2.7.0)
   byebug
   capybara (~> 2.13)
+  carrierwave (= 1.1.0)
   coffee-rails (~> 4.2)
   faker (~> 1.7.3)
   font-awesome-rails
   jbuilder (~> 2.5)
   jquery-rails (~> 4.3.1)
   listen (>= 3.0.5, < 3.2)
+  mini_magick (= 4.7.0)
   puma (~> 3.7)
   rails (~> 5.1.4)
   rails-controller-testing

+ 2 - 0
README.md

@@ -7,6 +7,8 @@ All SchoolPlatform source code is licensed under the MIT License. See [LICENSE.m
 
 ## Getting started
 
+First, install `imagemagick` using your favorite package manager.
+
 To get started with the app, clone the repo and then install the needed gems:
 
 ```

+ 4 - 0
app/assets/stylesheets/users.scss

@@ -7,6 +7,10 @@
     font-size: 2em;
   }
 
+  img.profile-picture {
+    float: right;
+  }
+
   ul {
     padding-left: 0;
     li {

+ 1 - 1
app/controllers/users_controller.rb

@@ -31,7 +31,7 @@ class UsersController < ApplicationController
     def user_params
       params.require(:user).permit(:login, :email, :password,
                                    :password_confirmation,
-                                   :gender, :phone)
+                                   :gender, :phone, :picture)
     end
 
     # Confirms the correct user.

+ 9 - 0
app/models/user.rb

@@ -26,6 +26,8 @@ class User < ApplicationRecord
 
   validates :birth_date, presence: true
 
+  mount_uploader :picture, PictureUploader
+  validate :picture_size
 
   # Returns the hash digest of the given string.
   def User.digest(string)
@@ -55,4 +57,11 @@ class User < ApplicationRecord
   def forget
     update_attribute(:remember_digest, nil)
   end
+
+  private
+    def picture_size
+      if picture.size > 5.megabytes
+        errors.add(:picture, "should be less than 5MB")
+      end
+    end
 end

+ 49 - 0
app/uploaders/picture_uploader.rb

@@ -0,0 +1,49 @@
+class PictureUploader < CarrierWave::Uploader::Base
+
+  # Include MiniMagick support:
+  include CarrierWave::MiniMagick
+  process resize_to_limit: [400, 400]
+
+  # Choose what kind of storage to use for this uploader:
+  storage :file
+
+  # Override the directory where uploaded files will be stored.
+  # This is a sensible default for uploaders that are meant to be mounted:
+  def store_dir
+    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
+  end
+
+  # Provide a default URL as a default if there hasn't been a file uploaded:
+  # def default_url(*args)
+  #   # For Rails 3.1+ asset pipeline compatibility:
+  #   # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
+  #
+  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
+  # end
+
+  # Create different versions of your uploaded files:
+  version :tiny do
+    process resize_to_fit: [20, 20]
+  end
+
+  version :small do
+    process resize_to_fit: [50, 50]
+  end
+
+  version :medium do
+    process resize_to_fit: [100, 100]
+  end
+
+  # Add a white list of extensions which are allowed to be uploaded.
+  # For images you might use something like this:
+  def extension_whitelist
+    %w(jpg jpeg gif png)
+  end
+
+  # Override the filename of the uploaded files:
+  # Avoid using model.id or version_name here, see uploader/store.rb for details.
+  # def filename
+  #   "something.jpg" if original_filename
+  # end
+
+end

+ 17 - 0
app/views/users/_picture_form.html.erb

@@ -0,0 +1,17 @@
+<%= bootstrap_form_for(@user) do |f| %>
+  <%= render 'shared/error_messages', object: f.object %>
+
+  <%= image_tag @user.picture.url if @user.picture? %>
+  <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
+
+  <%= f.submit "Save picture", class: "btn btn-primary" %>
+<% end %>
+
+<script type="text/javascript">
+  $('#user_picture').bind('change', function() {
+    var size_in_megabytes = this.files[0].size/1024/1024;
+    if (size_in_megabytes > 5) {
+      alert('Maximum file size is 5MB. Please choose a smaller file.');
+    }
+  });
+</script>

+ 3 - 0
app/views/users/edit.html.erb

@@ -6,4 +6,7 @@
   <div class="col-md-6">
     <%= render 'form' %>
   </div>
+  <div class="col-md-6">
+    <%= render 'picture_form' %>
+  </div>
 </div>

+ 4 - 1
app/views/users/show.html.erb

@@ -1,7 +1,10 @@
 <% provide(:title, @user.name) %>
 <div class="row">
-  <aside class="col-md-4">
+  <aside class="col-lg-4 col-md-6">
     <section class="user-info">
+      <%= link_to @user.picture.url do %>
+        <%= image_tag @user.picture.medium.url, class: 'profile-picture' if @user.picture? %>
+      <% end %>
       <h1>
         <%= @user.name %>
       </h1>

+ 5 - 0
config/initializers/skip_image_resizing.rb

@@ -0,0 +1,5 @@
+if Rails.env.test?
+  CarrierWave.configure do |config|
+    config.enable_processing = false
+  end
+end

+ 5 - 0
db/migrate/20171222122058_add_picture_to_users.rb

@@ -0,0 +1,5 @@
+class AddPictureToUsers < ActiveRecord::Migration[5.1]
+  def change
+    add_column :users, :picture, :string
+  end
+end

+ 2 - 1
db/schema.rb

@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20171220141141) do
+ActiveRecord::Schema.define(version: 20171222122058) do
 
   create_table "users", force: :cascade do |t|
     t.string "name"
@@ -23,6 +23,7 @@ ActiveRecord::Schema.define(version: 20171220141141) do
     t.integer "gender", default: 0
     t.string "phone"
     t.date "birth_date"
+    t.string "picture"
     t.index ["login"], name: "index_users_on_login", unique: true
   end