Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

36 Active storage #39

Merged
merged 9 commits into from May 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions Gemfile
Expand Up @@ -5,10 +5,13 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.3'

gem 'activestorage-dropbox' # service adapter for dropbox
gem 'dropbox_api' # dependency for the activestorage-dropbox gem
gem 'bootsnap', '>= 1.1.0', require: false # Reduces boot times through caching; required in config/boot.rb
gem 'coderay' # syntax highlighting: http://coderay.rubychan.de/
gem 'coffee-rails' # Use CoffeeScript for .coffee assets and views
gem 'coffee-rails' # Use CoffeeScripgt for .coffee assets and views
gem 'devise' # User authentication
gem 'image_processing', '~> 1.2'# Creates various sizes for ActiveStorage image files
gem 'jbuilder', '~> 2.5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'loofah', '>= 2.2.3' # Upgrade for security update
gem 'nokogiri', '>= 1.8.5' # Upgrade for security update
Expand All @@ -21,7 +24,7 @@ gem 'sass-rails', '~> 6.0' # Use SCSS for stylesheets
gem 'uglifier', '>= 1.3.0' # Use Uglifier as compressor for JavaScript assets
gem 'will_paginate', '~> 3.2.0' # pagination. Styles: http://mislav.github.io/will_paginate/
# gem 'redis', '~> 4.0' # Use Redis adapter to run Action Cable in production
# gem 'mini_magick', '~> 4.8' # Use ActiveStorage variant
gem 'mini_magick', '~> 4.8' # Use ActiveStorage variant
# gem 'capistrano-rails', group: :development # Use Capistrano for deployment

group :development, :test do
Expand Down
27 changes: 27 additions & 0 deletions Gemfile.lock
Expand Up @@ -111,6 +111,8 @@ GEM
activejob (= 6.0.2.2)
activerecord (= 6.0.2.2)
marcel (~> 0.3.1)
activestorage-dropbox (1.0.0)
dropbox_api (~> 0.1.16)
activesupport (6.0.2.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
Expand Down Expand Up @@ -167,6 +169,9 @@ GEM
responders
warden (~> 1.2.3)
diff-lcs (1.3)
dropbox_api (0.1.18)
faraday (<= 1.0)
oauth2 (~> 1.1)
equalizer (0.0.11)
erubi (1.9.0)
execjs (2.7.0)
Expand All @@ -175,6 +180,8 @@ GEM
factory_bot_rails (5.1.1)
factory_bot (~> 5.1.0)
railties (>= 4.2.0)
faraday (1.0.0)
multipart-post (>= 1.2, < 3)
ffi (1.12.2)
ffi (1.12.2-java)
ffi (1.12.2-x64-mingw32)
Expand All @@ -190,10 +197,14 @@ GEM
i18n (1.8.2)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
image_processing (1.11.0)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
jaro_winkler (1.5.4)
jaro_winkler (1.5.4-java)
jbuilder (2.10.0)
activesupport (>= 5.0.0)
jwt (2.2.1)
launchy (2.5.0)
addressable (~> 2.7)
listen (3.2.1)
Expand All @@ -209,13 +220,17 @@ GEM
mimemagic (~> 0.3.2)
method_source (1.0.0)
mimemagic (0.3.4)
mini_magick (4.10.1)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.0)
msgpack (1.3.3)
msgpack (1.3.3-java)
msgpack (1.3.3-x64-mingw32)
msgpack (1.3.3-x86-mingw32)
multi_json (1.14.1)
multi_xml (0.6.0)
multipart-post (2.1.1)
nio4r (2.5.2)
nio4r (2.5.2-java)
nokogiri (1.10.9)
Expand All @@ -225,6 +240,12 @@ GEM
mini_portile2 (~> 2.4.0)
nokogiri (1.10.9-x86-mingw32)
mini_portile2 (~> 2.4.0)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
orm_adapter (0.5.0)
parallel (1.19.1)
parser (2.7.1.1)
Expand Down Expand Up @@ -312,6 +333,8 @@ GEM
ruby-graphviz (1.2.5)
rexml
ruby-progressbar (1.10.1)
ruby-vips (2.0.17)
ffi (~> 1.9)
ruby2ruby (2.4.4)
ruby_parser (~> 3.1)
sexp_processor (~> 4.6)
Expand Down Expand Up @@ -407,6 +430,7 @@ PLATFORMS
x86-mswin32

DEPENDENCIES
activestorage-dropbox
awesome_print
better_errors
binding_of_caller
Expand All @@ -416,13 +440,16 @@ DEPENDENCIES
coderay
coffee-rails
devise
dropbox_api
factory_bot_rails
faker!
image_processing (~> 1.2)
jbuilder (~> 2.5)
launchy
listen (>= 3.0.5, < 3.3)
loofah (>= 2.2.3)
magic_frozen_string_literal
mini_magick (~> 4.8)
nokogiri (>= 1.8.5)
pg (>= 0.18, < 2.0)
pry-rails
Expand Down
7 changes: 6 additions & 1 deletion app/assets/stylesheets/shared.scss
Expand Up @@ -8,7 +8,10 @@
padding-top: 1rem;
}

.image { width: 100%; }
.image {
max-width: 600px;
width: 100%;
}

.environment-banner {
color: $white;
Expand Down Expand Up @@ -36,6 +39,8 @@ a { color: $link-color; }
}
}

.file-field { color: $medium-gray; }


// SEARCH BAR
.search-icon {
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/posts_controller.rb
Expand Up @@ -40,7 +40,7 @@ def update
end

def destroy
@post.destroy
@post.destroy
respond_to do |format|
format.html { redirect_to post_type_url(id: @post.post_type.id), notice: "#{@post.date} #{@post.post_type_name} was successfully deleted." }
format.json { head :no_content }
Expand All @@ -60,7 +60,9 @@ def post_params
:date,
:description,
:with_people,
:image,
:image_url,
:remove_attached_image,
:url,
category_ids: [])
end
Expand Down
28 changes: 27 additions & 1 deletion app/models/post.rb
Expand Up @@ -4,7 +4,9 @@ class Post < ApplicationRecord
belongs_to :post_type
has_many :post_categories, dependent: :destroy
has_many :categories, through: :post_categories
has_one_attached :image

validate :acceptable_image
validates :date,
:description,
:post_type,
Expand All @@ -18,6 +20,9 @@ class Post < ApplicationRecord
scope :by_date, -> { order(date: :desc) }
scope :in_chronological_order, -> { order(date: :asc) }

attr_accessor :remove_attached_image
after_save :purge_attached_image, if: :remove_attached_image?

def self.search(given_year: '', search_terms: '')
return for_year(Report.this_year) if given_year.blank? && search_terms.blank?

Expand Down Expand Up @@ -84,11 +89,32 @@ def word_cloud
end

def format_image_url
self.image_url = image_url.present? ? DropboxApi.format_url(self.image_url) : ''
self.image_url = image_url.present? ? DropboxService.format_url(self.image_url) : ''
end

def acceptable_image
return unless image.attached?

unless image.byte_size <= 1.megabyte
errors.add(:image, "is too big")
end

acceptable_types = ['image/jpeg', 'image/png']
unless acceptable_types.include?(image.content_type)
errors.add(:image, 'must be a JPEG or PNG')
end
end

private

def remove_attached_image?
remove_attached_image == '1'
end

def purge_attached_image
image.purge_later
end

def stripped_word(word)
unwanted_characters = %w[: " . ( ) [ ] , … ... ? — -- & ; 0 1 2 3 4 5 6 7 8 9]
unwanted_characters.each do |mark|
Expand Down
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class DropboxApi
class DropboxService
DOMAIN = 'www.dropbox.com'
READABLE_DOMAIN = 'dl.dropboxusercontent.com'

Expand Down
15 changes: 15 additions & 0 deletions app/views/posts/_form.html.erb
Expand Up @@ -31,6 +31,21 @@
<%= form.text_field :image_url, class: 'form-control' %>
</div>

<div class="field">
<%= form.label :image %>
<% if post.image.attached? %>
<p>
<%= image_tag(post.image.variant(resize_to_limit: [75, 75])) %><br>
<%= post.image.filename %>
</p>
<div class='form-check'>
<%= form.check_box :remove_attached_image, class: 'form-check-input' %>
<%= form.label 'Check to remove attached image', class: 'form-check-label' %>
</div>
<% end %>
<%= form.file_field :image, class: 'mt-2 file-field' %>
</div>

<div class="field">
<%= form.label :with_people %>
<%= form.text_field :with_people, class: 'form-control' %>
Expand Down
1 change: 1 addition & 0 deletions app/views/posts/_post.html.erb
Expand Up @@ -7,6 +7,7 @@
<span class="float-right ml-2"><%= link_to 'edit', edit_post_path(post), class: button_class('btn btn-sm btn-light float-right ml-2') %></span>
</div>
<div class="card-body">
<%= image_tag(post.image, class: 'image', title: post.date) if post.image.present? %>
<%= image_tag(post.image_url, class: 'image', title: post.date) if post.image_url.present? %>
<% if post.with_people.present? %>
<p class="card-title">with <%= post.with_people %>...</p>
Expand Down
2 changes: 1 addition & 1 deletion config/credentials.yml.enc
@@ -1 +1 @@
VIObN77Wr26ipTAcytCoTPbGsYHdP6U3Pm2pxHVZUmA3LHhgq/uXusUlX7cuA5K6EoJkAPXJymNeUawzCzXc/tEzwn6/nzpo16h97tykUI+VWCJpy73TRbQkrG2E3pjoKLKFSXMb4+rrMUjpdnerxu96ctRLG7GKG5nU2Kg1cz25QwKl/9H9K5s/KMqivkPuFz205UipSOC6aNfA5Nh8LaoWDYcTWi4Depkd9c6E+2zAVrjhDmFav2SRK+km7ll6TZ/0JH3NenW6oGjzSn9bogXgeGkZlT0xe4fxa3O8qt1ywcdoTqNL0q7Fxxuc1HJSb8P2Xc8pZFMuPOH2ET8qRx5XTJnasNXCVl3luykvZ2C30M6TnT8zjAj542R7PeDkBG6W8uEQmrkS8/OzIPvyY11vOag82fp0fZeQ--xEdSc5RB6Crd8/fg--fu+uDE5DTypwzH6xuLIZfw==
XSIp6XZSkOwYweZqOn3owbN1tM1vLm+ofFtvZdH3ItmuIXs3RN80t9XI1MvMlrUZ3Gwa+E5pmI+v4MJXf624YtT7fK/H1kWWOsFSASESHi87SlPCCtVHbSGMT6E1zF2DHcOISWVqzKLPaGjkypAV6M1XBsoraYfVCmkRsBCoW01L+PW7bZc4fsTsSAFiWYRRLv3+NcLrKWpyyQXpTBPsjCeVrJtksPE3AKLNzLLHaw2CFBJITdJyRVVzb4OAGD3tlWRnJ3NbD9g3/vT4AesNa36zdMrNiymFZUjpMHVggDcwxH6NLfm2Vx7DFWGH9XWlXg2gT4NhpuooenECohZeuuHvmK7C12J4O3RPj1Sfth701uNLfEVlvMAthMXSGxn9t17+x+dV7j/xEfk53bqJerRpSf5qmlumCFc3nVXdUeL27v3hIT6Wi9wolkBjxOYkmiZpt9Zs9PfRt3uwsvkVs/yWZ4pg+lHMg1XhnOD2A8ONiofH0Ru7KJIxejL4lLPrH0/HzBTG9xkGVcY/FqsrswdyT4vvu42ymV5Lu/oBBUF0nsirr09KYySHIGESy7CXP+uwtceZjBPpdPFPg2VsJ4vG3bAlH5GMSbJWCU6rGsJ6I5o3AF3zZOw90tRW9qQkPXKOtQbBHO8tvoWDae75l8PsuaPVwo4WZsnkHd+YwQ==--xweim5WjsX6R+CJt--tdCB1gNPYVJHJ9nsWybaQA==
1 change: 1 addition & 0 deletions config/environments/development.rb
Expand Up @@ -31,6 +31,7 @@

# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local
# config.active_storage.service = :dropbox

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
Expand Down
4 changes: 3 additions & 1 deletion config/environments/production.rb
Expand Up @@ -42,7 +42,9 @@
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local
config.active_storage.service = :dropbox
# config.active_storage.service = :local


# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil
Expand Down
8 changes: 8 additions & 0 deletions config/storage.yml
Expand Up @@ -6,6 +6,14 @@ local:
service: Disk
root: <%= Rails.root.join("storage") %>

dropbox:
service: Dropbox
app_key: <%= Rails.application.credentials.dig(:dropbox, :app_key) %>
app_secret: <%= Rails.application.credentials.dig(:dropbox, :app_secret) %>
access_token: <%= Rails.application.credentials.dig(:dropbox, :access_token) %>
user_id: <%= Rails.application.credentials.dig(:dropbox, :user_id) %>
access_type: <%= Rails.application.credentials.dig(:dropbox, :access_type) %>

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
# service: S3
Expand Down
@@ -0,0 +1,27 @@
# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
create_table :active_storage_blobs do |t|
t.string :key, null: false
t.string :filename, null: false
t.string :content_type
t.text :metadata
t.bigint :byte_size, null: false
t.string :checksum, null: false
t.datetime :created_at, null: false

t.index [ :key ], unique: true
end

create_table :active_storage_attachments do |t|
t.string :name, null: false
t.references :record, null: false, polymorphic: true, index: false
t.references :blob, null: false

t.datetime :created_at, null: false

t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
end
24 changes: 23 additions & 1 deletion db/schema.rb
Expand Up @@ -10,11 +10,32 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2020_03_11_121715) do
ActiveRecord::Schema.define(version: 2020_05_19_002207) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
t.bigint "record_id", null: false
t.bigint "blob_id", null: false
t.datetime "created_at", null: false
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
end

create_table "active_storage_blobs", force: :cascade do |t|
t.string "key", null: false
t.string "filename", null: false
t.string "content_type"
t.text "metadata"
t.bigint "byte_size", null: false
t.string "checksum", null: false
t.datetime "created_at", null: false
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
end

create_table "categories", force: :cascade do |t|
t.string "name"
t.bigint "user_id", null: false
Expand Down Expand Up @@ -68,6 +89,7 @@
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "categories", "users"
add_foreign_key "post_categories", "categories"
add_foreign_key "post_categories", "posts"
Expand Down
Binary file modified erd.pdf
Binary file not shown.