diff --git a/Gemfile b/Gemfile index b44f9be..29f7215 100644 --- a/Gemfile +++ b/Gemfile @@ -3,13 +3,13 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.3.4' gem 'active_model_serializers', '~> 0.10.0' +gem 'aws-sdk-s3', require: false gem 'bootsnap', '>= 1.1.0', require: false gem 'pg', '>= 0.18', '< 2.0' gem 'puma', '~> 3.11' gem 'rack-cors', require: 'rack/cors' gem 'rails', '~> 5.2.0.rc2' - group :development, :test do gem 'coveralls', require: false gem 'factory_bot_rails' diff --git a/Gemfile.lock b/Gemfile.lock index 7ed97bc..be3be73 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -48,6 +48,19 @@ GEM minitest (~> 5.1) tzinfo (~> 1.1) arel (9.0.0) + aws-partitions (1.77.0) + aws-sdk-core (3.19.0) + aws-partitions (~> 1.0) + aws-sigv4 (~> 1.0) + jmespath (~> 1.0) + aws-sdk-kms (1.5.0) + aws-sdk-core (~> 3) + aws-sigv4 (~> 1.0) + aws-sdk-s3 (1.9.0) + aws-sdk-core (~> 3) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.0) + aws-sigv4 (1.0.2) bootsnap (1.2.1) msgpack (~> 1.0) builder (3.2.3) @@ -80,6 +93,7 @@ GEM domain_name (~> 0.5) i18n (1.0.0) concurrent-ruby (~> 1.0) + jmespath (1.4.0) json (2.1.0) jsonapi-renderer (0.2.0) jsonapi-rspec (0.0.2) @@ -210,6 +224,7 @@ PLATFORMS DEPENDENCIES active_model_serializers (~> 0.10.0) + aws-sdk-s3 bootsnap (>= 1.1.0) coveralls factory_bot_rails diff --git a/app/models/athlete.rb b/app/models/athlete.rb index 9a73270..65288ac 100644 --- a/app/models/athlete.rb +++ b/app/models/athlete.rb @@ -1,3 +1,4 @@ class Athlete < ApplicationRecord validates :name, :age, :home, presence: true + has_one_attached :image end diff --git a/app/serializers/athlete/show_serializer.rb b/app/serializers/athlete/show_serializer.rb index 469b6a3..0f82503 100644 --- a/app/serializers/athlete/show_serializer.rb +++ b/app/serializers/athlete/show_serializer.rb @@ -1,3 +1,9 @@ class Athlete::ShowSerializer < ActiveModel::Serializer - attributes :name, :age, :home, :starttime + attributes :name, :age, :home, :starttime, :image + + def image + unless object.image.attachment.nil? + object.image.service_url(expires_in: 1.hour, disposition: 'inline') + end + end end diff --git a/app/serializers/athlete_serializer.rb b/app/serializers/athlete_serializer.rb index 0652683..8cea178 100644 --- a/app/serializers/athlete_serializer.rb +++ b/app/serializers/athlete_serializer.rb @@ -1,8 +1,14 @@ class AthleteSerializer < ActiveModel::Serializer include Rails.application.routes.url_helpers - attributes :name, :link, :home + attributes :name, :link, :home, :image def link api_v1_athlete_url(object) end + + def image + unless object.image.attachment.nil? + object.image.service_url(expires_in: 1.hour, disposition: 'inline') + end + end end diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index d392919..9f4530c 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -MckhkBgeP9c2MN502PBpQkcNBszdK5YX6k7KaWdMJa4XVU96Gj6Ah3aVXzQuFusbtbbcR1o3V6IuRd6CMZrboFcx398Q+aTnzerXlJWx6AmczRwmDLER6+MnuWw51N3bVFNZmTgfb2T3zBcrZsNHc6PUIakX3i+VGXBbtrrhGis7fmoFk4q5ay5YwtBd3YszYjVCQ3NHk4iyNimssQIZIJg+xxYFtHjec13VJdt4WCI/3sH9Cffd0iDL3Pzc9kiqLyyc8KAGe0zzeb4cofci81z+b3j0D2AkCNFP55tJ8Rm0TG8/i5WEu664X1klUDjJPx1R1gR0+B1rDrT3+bIdfI/5h4s40kqC3uFKz0uoteHAyPQeY0AY8c1yU49h/2SPZxC/HYPOQ6z6DSU+G/t6is1eDyFPvr3vhTc4--PcMzhR/7lgpZ60sb--7a8HeHPW40+uc+Z1F2h++g== \ No newline at end of file +ut8x0Vl45ypRpbBsurUM/eTTubSo7cpAMEhLU/43+gNL0zbr9gXk+Qf6yWxXlBPqafusQL96YupVaQzHsBfRBYJIKuz0Ea12qY2xQKMOdqvIjjRz3L3SPfs7qFqWnj+srTupYg7pklxqTqPYQSiPFIt20dMpW17o1/FMnW2TJKeQhSypQ5cSnSWUbSGiIMgkb+FHdXbdi1XtY/LvBspDBiwsDmrX8fno9HktyuSvvn6KAdr53AC0cjtt7amyCAS2RBPab6LCYWzpCNuGpPxibIPkCqleQv3vI7hHepQRBGbfIczqwH/amM7YwSJUUKOpoz/i2s0BJ/OVc474BUtsQYB3W68fX9qJGM8UL+WfXsR29Usj3JpcnFQhOy8t25HHJ+tN5v7FWrkSc4z9Kicktm18NQeK7xrSK83lCm3dS67OmteppeFg9UFQCvTX1T9QzZH9zjvFYvyVqETEItp3ij4+99wH--NojC0boXV2MgNu89--08jQ6RGrSWm+/bR8zxWgtA== \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 586c637..2432e7f 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -17,7 +17,7 @@ config.cache_store = :null_store end - config.active_storage.service = :local + config.active_storage.service = :amazon config.action_mailer.raise_delivery_errors = false config.action_mailer.perform_caching = false config.active_support.deprecation = :log diff --git a/config/environments/production.rb b/config/environments/production.rb index b0c1996..a645df8 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -30,7 +30,7 @@ # 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 = :amazon # Mount Action Cable outside main process or domain # config.action_cable.mount_path = nil diff --git a/config/environments/test.rb b/config/environments/test.rb index d8f5435..5709aec 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -40,7 +40,7 @@ # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - + # Raises error for missing translations # config.action_view.raise_on_missing_translations = true diff --git a/config/storage.yml b/config/storage.yml index d32f76e..25e169a 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -7,12 +7,12 @@ local: root: <%= Rails.root.join("storage") %> # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) -# amazon: -# service: S3 -# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> -# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> -# region: us-east-1 -# bucket: your_own_bucket +amazon: + service: S3 + access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> + secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> + region: eu-central-1 + bucket: bninvitational # Remember not to checkin your GCS keyfile to a repository # google: diff --git a/db/migrate/20180405180045_create_active_storage_tables.active_storage.rb b/db/migrate/20180405180045_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000..360e0d1 --- /dev/null +++ b/db/migrate/20180405180045_create_active_storage_tables.active_storage.rb @@ -0,0 +1,26 @@ +# 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 + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4eb3267..8d06431 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,11 +10,32 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_04_04_125327) do +ActiveRecord::Schema.define(version: 2018_04_05_180045) 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 "athletes", force: :cascade do |t| t.string "name" t.string "home" diff --git a/spec/fixtures/dummy_image.jpg b/spec/fixtures/dummy_image.jpg new file mode 100644 index 0000000..46961bb Binary files /dev/null and b/spec/fixtures/dummy_image.jpg differ diff --git a/spec/fixtures/files/athlete.txt b/spec/fixtures/files/athlete.txt index 4f9ce71..52e094e 100644 --- a/spec/fixtures/files/athlete.txt +++ b/spec/fixtures/files/athlete.txt @@ -5,5 +5,6 @@ "name" => "#{athlete.name}", "age" => athlete.age, "home" => "#{athlete.home}", -"starttime" => athlete.starttime +"starttime" => athlete.starttime, +"image" => nil }}} diff --git a/spec/fixtures/files/athlete_list.txt b/spec/fixtures/files/athlete_list.txt index 6759972..db7c621 100644 --- a/spec/fixtures/files/athlete_list.txt +++ b/spec/fixtures/files/athlete_list.txt @@ -4,5 +4,6 @@ "attributes" => { "name" => "#{athlete.name}", "link" => "https://votingapi.herokuapp.com/api/v1/athletes/#{athlete.id}", -"home" => "#{athlete.home}" +"home" => "#{athlete.home}", +"image" => nil }}]} diff --git a/spec/models/athlete_spec.rb b/spec/models/athlete_spec.rb index dd0d284..f04f62e 100644 --- a/spec/models/athlete_spec.rb +++ b/spec/models/athlete_spec.rb @@ -20,4 +20,11 @@ it {is_expected.to validate_presence_of :age} it {is_expected.to validate_presence_of :home} end + + describe 'Attachment' do + it 'is valid ' do + subject.image.attach(io: File.open(fixture_path + '/dummy_image.jpg'), filename: 'attachment.jpg', content_type: 'image/jpg') + expect(subject.image).to be_attached + end + end end diff --git a/spec/models/result_spec.rb b/spec/models/result_spec.rb index 2d461cb..a6cf611 100644 --- a/spec/models/result_spec.rb +++ b/spec/models/result_spec.rb @@ -12,7 +12,7 @@ athlete = create(:athlete) expect(create(:result, athlete: athlete).valid?).to eq true end - end + end describe 'Assosiation' do it {is_expected.to belong_to :athlete} diff --git a/spec/requests/api/v1/display_athletes_spec.rb b/spec/requests/api/v1/display_athletes_spec.rb index 3b410a8..9f53100 100644 --- a/spec/requests/api/v1/display_athletes_spec.rb +++ b/spec/requests/api/v1/display_athletes_spec.rb @@ -2,7 +2,9 @@ RSpec.describe Api::V1::AthletesController, type: :request do describe 'GET /api/v1/athletes' do let!(:athlete) { create(:athlete) } - let(:object) { JSON.parse(response.body)} + let(:object) { JSON.parse(response.body) } + before do + end it 'Should return a list of all athletes' do get '/api/v1/athletes' @@ -15,5 +17,10 @@ expected_response = eval(file_fixture('athlete.txt').read) expect(object).to eq expected_response end + it 'should return athletes image' do + athlete.image.attach(io: File.open(fixture_path + '/dummy_image.jpg'), filename: 'attachment.jpg', content_type: 'image/jpg') + get "/api/v1/athletes/#{athlete.id}" + expect(object['data']).to have_attribute(:image) + end end end