From 4d8f5162521e2f82735eabe25c8cc3ad01f508f5 Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Fri, 16 Nov 2018 17:14:53 -0500 Subject: [PATCH] Remove Dragonfly and fix up specs --- Gemfile | 1 - Gemfile.lock | 5 --- README.md | 2 +- app/jobs/tag_image_job.rb | 2 +- app/models/image.rb | 3 +- app/models/user.rb | 3 -- app/validators/attached_validator.rb | 7 +++ config/initializers/dragonfly.rb | 27 ----------- config/locales/en.yml | 5 +++ lib/clarifai.rb | 12 +++-- spec/features/user_manages_image_spec.rb | 8 +++- spec/features/user_manages_image_tags_spec.rb | 24 +++++++--- spec/jobs/tag_image_job_spec.rb | 7 ++- spec/lib/clarifai_spec.rb | 2 +- spec/models/image_spec.rb | 8 +--- spec/support/matchers/have_attached_file.rb | 7 +++ .../matchers/validate_attachment_of.rb | 45 +++++++++++++++++++ 17 files changed, 104 insertions(+), 64 deletions(-) create mode 100644 app/validators/attached_validator.rb delete mode 100644 config/initializers/dragonfly.rb create mode 100644 spec/support/matchers/have_attached_file.rb create mode 100644 spec/support/matchers/validate_attachment_of.rb diff --git a/Gemfile b/Gemfile index bf985e8..f12124c 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,6 @@ gem "dotenv-rails", groups: %i[development test] gem "rails", "5.2.1" gem "delayed_job_active_record" -gem "dragonfly" gem "http" gem "mini_magick" gem "omniauth-github" diff --git a/Gemfile.lock b/Gemfile.lock index abd0884..14f53d4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,10 +82,6 @@ GEM dotenv-rails (2.5.0) dotenv (= 2.5.0) railties (>= 3.2, < 6.0) - dragonfly (1.1.5) - addressable (~> 2.3) - multi_json (~> 1.0) - rack (>= 1.3) erubi (1.7.1) execjs (2.7.0) faraday (0.12.2) @@ -267,7 +263,6 @@ DEPENDENCIES capybara delayed_job_active_record dotenv-rails - dragonfly geckodriver-helper http launchy diff --git a/README.md b/README.md index b531719..6ad2828 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [ ![Codeship Status for danbee/my-images](https://app.codeship.com/projects/cf564ea0-7cbe-0136-47c4-2ebac98daaef/status?branch=master)](https://app.codeship.com/projects/300990) -A simple DragonFly powered image storage application. +A simple Active Storage powered image storage application. ![](https://user-images.githubusercontent.com/165531/43842691-e38186be-9af3-11e8-9387-d1ee206cca2e.png) diff --git a/app/jobs/tag_image_job.rb b/app/jobs/tag_image_job.rb index ac84935..5a9603d 100644 --- a/app/jobs/tag_image_job.rb +++ b/app/jobs/tag_image_job.rb @@ -4,7 +4,7 @@ class TagImageJob < ApplicationJob def perform(image_id:) image = Image.find(image_id) - tags = Clarifai.new(image.image.file.path).tags + tags = Clarifai.new(image.image.download).tags image.update_attributes(tags: tags) end end diff --git a/app/models/image.rb b/app/models/image.rb index 1e31197..abf3346 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -1,8 +1,7 @@ class Image < ActiveRecord::Base - dragonfly_accessor :df_image has_one_attached :image - validates :image, presence: true + validates :image, attached: true belongs_to :user end diff --git a/app/models/user.rb b/app/models/user.rb index 1fcfad9..e818b79 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,4 @@ class User < ActiveRecord::Base - dragonfly_accessor :avatar - has_many :images def self.find_or_create_from_auth(auth) @@ -13,7 +11,6 @@ class User < ActiveRecord::Base uid: auth.uid, username: auth.info.nickname, name: auth.info.name, - avatar_url: auth.info.image, ) end end diff --git a/app/validators/attached_validator.rb b/app/validators/attached_validator.rb new file mode 100644 index 0000000..b860bc1 --- /dev/null +++ b/app/validators/attached_validator.rb @@ -0,0 +1,7 @@ +class AttachedValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + if !value.attached? + record.errors.add(attribute, :attached, options) + end + end +end diff --git a/config/initializers/dragonfly.rb b/config/initializers/dragonfly.rb deleted file mode 100644 index 8e8ef5f..0000000 --- a/config/initializers/dragonfly.rb +++ /dev/null @@ -1,27 +0,0 @@ -require "dragonfly" - -# Configure -Dragonfly.app.configure do - plugin :imagemagick - - verify_urls true - secret "0da375f9754c75707f2a3b4e0c75dffb7ec7d6bb1a4a77e8a8dcfba9037bebce" - - url_format "/media/:job/:name" - - datastore :file, - root_path: Rails.root.join("public/system/dragonfly", Rails.env), - server_root: Rails.root.join("public") -end - -# Logger -Dragonfly.logger = Rails.logger - -# Mount as middleware -Rails.application.middleware.use Dragonfly::Middleware - -# Add model functionality -if defined?(ActiveRecord::Base) - ActiveRecord::Base.extend Dragonfly::Model - ActiveRecord::Base.extend Dragonfly::Model::Validations -end diff --git a/config/locales/en.yml b/config/locales/en.yml index 0653957..c0523a6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -21,3 +21,8 @@ en: hello: "Hello world" + + activerecord: + errors: + messages: + attached: is not attached diff --git a/lib/clarifai.rb b/lib/clarifai.rb index a12efb2..60be6ae 100644 --- a/lib/clarifai.rb +++ b/lib/clarifai.rb @@ -6,8 +6,8 @@ class Clarifai API_URL = "https://api.clarifai.com/v2/models/" \ "aaa03c23b3724a16a56b629203edc62c/outputs".freeze - def initialize(image_path) - @image_path = image_path + def initialize(image_data) + @image_data = image_data end def tags @@ -16,6 +16,8 @@ class Clarifai private + attr_reader :image_data + def extract_tags(response_hash) response_hash["outputs"][0]["data"]["concepts"].map do |concept| concept["name"] @@ -40,10 +42,6 @@ class Clarifai end def image_base64 - Base64.encode64(image_file) - end - - def image_file - File.read(@image_path) + Base64.encode64(image_data) end end diff --git a/spec/features/user_manages_image_spec.rb b/spec/features/user_manages_image_spec.rb index 66c7a46..bd94a1a 100644 --- a/spec/features/user_manages_image_spec.rb +++ b/spec/features/user_manages_image_spec.rb @@ -15,10 +15,14 @@ feature "user manages images" do it "deletes the image" do user = User.create(uid: "1") - Image.create( + image = Image.new( user: user, - image: File.new("#{Rails.root}/spec/fixtures/spectrum.jpg"), ) + image.image.attach( + io: File.open("#{Rails.root}/spec/fixtures/spectrum.jpg"), + filename: "spectrum.jpg", + ) + image.save sign_in(user) click_on("Delete") diff --git a/spec/features/user_manages_image_tags_spec.rb b/spec/features/user_manages_image_tags_spec.rb index ce41408..318d4cd 100644 --- a/spec/features/user_manages_image_tags_spec.rb +++ b/spec/features/user_manages_image_tags_spec.rb @@ -4,11 +4,15 @@ feature "user manages image tags by visitng images show page" do scenario "and can see an X to link for deletion on a tag" do tags = ["one", "two"] user = User.create(uid: "123") - Image.create( + image = Image.new( user: user, tags: tags, - image: File.new("#{Rails.root}/spec/fixtures/spectrum.jpg"), ) + image.image.attach( + io: File.open("#{Rails.root}/spec/fixtures/spectrum.jpg"), + filename: "spectrum.jpg", + ) + image.save sign_in(user) page.find(".image").click @@ -21,11 +25,15 @@ feature "user manages image tags by visitng images show page" do scenario "and can click the link to delete a tag", js: true do tags = ["one", "two"] user = User.create(uid: "123") - Image.create( + image = Image.new( user: user, tags: tags, - image: File.new("#{Rails.root}/spec/fixtures/spectrum.jpg"), ) + image.image.attach( + io: File.open("#{Rails.root}/spec/fixtures/spectrum.jpg"), + filename: "spectrum.jpg", + ) + image.save sign_in(user) page.find(".image").click @@ -41,11 +49,15 @@ feature "user manages image tags by visitng images show page" do tags = ["one", "two"] user = User.create(uid: "123") new_tag = "newtag" - Image.create( + image = Image.new( user: user, tags: tags, - image: File.new("#{Rails.root}/spec/fixtures/spectrum.jpg"), ) + image.image.attach( + io: File.open("#{Rails.root}/spec/fixtures/spectrum.jpg"), + filename: "spectrum.jpg", + ) + image.save sign_in(user) page.find(".image").click diff --git a/spec/jobs/tag_image_job_spec.rb b/spec/jobs/tag_image_job_spec.rb index 2244725..d88d503 100644 --- a/spec/jobs/tag_image_job_spec.rb +++ b/spec/jobs/tag_image_job_spec.rb @@ -4,9 +4,12 @@ describe TagImageJob, type: :job do describe ".perform" do it "tags an image" do stub_clarifai(%w[computers technology]) - image = Image.create( - image: "#{Rails.root}/spec/fixtures/spectrum.jpg", + image = Image.new + image.image.attach( + io: File.open("#{Rails.root}/spec/fixtures/spectrum.jpg"), + filename: "spectrum.jpg", ) + image.save TagImageJob.perform_now(image_id: image.id) image.reload diff --git a/spec/lib/clarifai_spec.rb b/spec/lib/clarifai_spec.rb index cef4a8d..80e6ed5 100644 --- a/spec/lib/clarifai_spec.rb +++ b/spec/lib/clarifai_spec.rb @@ -11,7 +11,7 @@ describe Clarifai do it "predicts tags for our image" do stub_api(%w[computer technology]) - clarifai = Clarifai.new("spec/fixtures/spectrum.jpg") + clarifai = Clarifai.new(File.read("spec/fixtures/spectrum.jpg")) expect(clarifai.tags).to eq(%w[computer technology]) end diff --git a/spec/models/image_spec.rb b/spec/models/image_spec.rb index c534807..3c490b6 100644 --- a/spec/models/image_spec.rb +++ b/spec/models/image_spec.rb @@ -1,11 +1,7 @@ require "rails_helper" describe Image do - it { is_expected.to validate_presence_of(:image) } it { is_expected.to belong_to(:user) } - - it "should not be valid without an image" do - image = Image.new - expect(image).not_to be_valid - end + it { is_expected.to have_attached_file(:image) } + it { is_expected.to validate_attachment_of(:image) } end diff --git a/spec/support/matchers/have_attached_file.rb b/spec/support/matchers/have_attached_file.rb new file mode 100644 index 0000000..107e026 --- /dev/null +++ b/spec/support/matchers/have_attached_file.rb @@ -0,0 +1,7 @@ +RSpec::Matchers.define :have_attached_file do |name| + match do |record| + file = record.send(name) + + file.respond_to?(:attach) + end +end diff --git a/spec/support/matchers/validate_attachment_of.rb b/spec/support/matchers/validate_attachment_of.rb new file mode 100644 index 0000000..955cc81 --- /dev/null +++ b/spec/support/matchers/validate_attachment_of.rb @@ -0,0 +1,45 @@ +require "rspec/expectations" + +RSpec::Matchers.define :validate_attachment_of do |attr_name| + match do |record| + matcher.matches?(record, attr_name) + end + + chain :on do |validation_context| + matcher.on(validation_context) + end + + chain :with_message do |message| + matcher.with_message(message) + end + + private + + def matcher + @matcher ||= ValidateAttachmentOfMatcher.new + end + + class ValidateAttachmentOfMatcher + def on(validation_context) + @validation_context = validation_context + end + + def with_message(message) + @message = message + end + + def matches?(record, attr_name) + record.send(attr_name).purge + record.valid?(validation_context) + record.errors[attr_name].include? message + end + + private + + attr_reader :validation_context + + def message + @message || I18n.translate("activerecord.errors.messages.attached") + end + end +end