diff --git a/.DS_Store b/.DS_Store index 175ed52..78f3bb9 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Gemfile b/Gemfile index 98767cc..78d2eea 100644 --- a/Gemfile +++ b/Gemfile @@ -70,3 +70,4 @@ gem 'carrierwave' gem 'sassc' gem 'rubocop', '~> 0.47.1' gem 'htmlbeautifier' +gem 'activerecord-import' diff --git a/Gemfile.lock b/Gemfile.lock index 1fa33bf..9c2cc67 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,6 +33,8 @@ GEM activemodel (= 5.2.3) activesupport (= 5.2.3) arel (>= 9.0) + activerecord-import (1.0.2) + activerecord (>= 3.2) activestorage (5.2.3) actionpack (= 5.2.3) activerecord (= 5.2.3) @@ -102,7 +104,7 @@ GEM io-like (0.3.0) jbuilder (2.9.1) activesupport (>= 4.2.0) - jquery-rails (4.3.3) + jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) @@ -125,7 +127,7 @@ GEM mini_mime (1.0.1) mini_portile2 (2.4.0) minitest (5.11.3) - msgpack (1.2.10) + msgpack (1.3.0) nio4r (2.3.1) nokogiri (1.10.3) mini_portile2 (~> 2.4.0) @@ -173,12 +175,12 @@ GEM rb-inotify (0.10.0) ffi (~> 1.0) regexp_parser (1.5.1) - rspec-core (3.8.0) + rspec-core (3.8.1) rspec-support (~> 3.8.0) - rspec-expectations (3.8.3) + rspec-expectations (3.8.4) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) - rspec-mocks (3.8.0) + rspec-mocks (3.8.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-rails (3.8.2) @@ -189,7 +191,7 @@ GEM rspec-expectations (~> 3.8.0) rspec-mocks (~> 3.8.0) rspec-support (~> 3.8.0) - rspec-support (3.8.0) + rspec-support (3.8.2) rubocop (0.47.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) @@ -245,9 +247,9 @@ GEM activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) - websocket-driver (0.7.0) + websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.3) + websocket-extensions (0.1.4) xpath (3.2.0) nokogiri (~> 1.8) @@ -255,6 +257,7 @@ PLATFORMS ruby DEPENDENCIES + activerecord-import bootsnap (>= 1.1.0) bootstrap byebug diff --git a/app/assets/javascripts/ad_api.coffee b/app/assets/javascripts/ad_api.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/ad_api.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/ad_api.scss b/app/assets/stylesheets/ad_api.scss new file mode 100644 index 0000000..b15c608 --- /dev/null +++ b/app/assets/stylesheets/ad_api.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Ad_API controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/ad_api_controller.rb b/app/controllers/ad_api_controller.rb new file mode 100644 index 0000000..20d6dba --- /dev/null +++ b/app/controllers/ad_api_controller.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true +class AdApiController < ApplicationController + def get_ads + array = [] + reports = [] + + target_ids = Ad.pluck(:id).sample(params[:count].to_i) + ads = Ad.find(target_ids) + ads.each do |ad| + report = Report.find_by(ad_id: ad.id, adspot_id: params[:adspot_id],date: Date.today) + unless report + report = Report.new(ad_id: ad.id, adspot_id: params[:adspot_id], date: Date.today) + end + + report.imp += 1 + reports.push(report) + + array.push( + img_url: ad.image.url, + body: ad.text, + ad_id: ad.id + ) + end + Report.import reports, on_duplicate_key_update: [:imp] + render json: array + end + + def update_clicks + report = Report.find_by(ad_id: params[:ad_id], adspot_id: params[:adspot_id],date: Date.today) + unless report + report = Report.new(ad_id: params[:ad_id], adspot_id: params[:adspot_id], date: Date.today) + end + report.click += 1 + report.price += Ad.find(params[:ad_id]).price + report.save + end + +end + diff --git a/app/helpers/ad_api_helper.rb b/app/helpers/ad_api_helper.rb new file mode 100644 index 0000000..b9fd8b9 --- /dev/null +++ b/app/helpers/ad_api_helper.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true +module AdApiHelper +end diff --git a/app/models/report.rb b/app/models/report.rb new file mode 100644 index 0000000..eb2599f --- /dev/null +++ b/app/models/report.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true +class Report < ApplicationRecord +end diff --git a/app/views/ad/index.html.erb b/app/views/ad/index.html.erb index 7296a3d..e322ba3 100644 --- a/app/views/ad/index.html.erb +++ b/app/views/ad/index.html.erb @@ -14,14 +14,14 @@ <%= image_tag ad.image.to_s %>
- <%= link_to("Edit", edit_ad_path(ad)) %> + <%= link_to("変更", edit_ad_path(ad)) %>
- <%= link_to("Delete", ad_path(ad) ,method: :delete) %> + <%= link_to("削除", ad_path(ad) ,method: :delete) %>
<% end %>
- <%= link_to("New", new_ad_path) %> + <%= link_to("新規作成", new_ad_path) %>
diff --git a/app/views/ad_api/update_clicks.erb b/app/views/ad_api/update_clicks.erb new file mode 100644 index 0000000..e3e77a6 --- /dev/null +++ b/app/views/ad_api/update_clicks.erb @@ -0,0 +1,2 @@ +

AdApi#click

+

Find me in app/views/ad_api/click.html.erb

diff --git a/app/views/ad_api/view_make_report.html.erb b/app/views/ad_api/view_make_report.html.erb new file mode 100644 index 0000000..b5fd078 --- /dev/null +++ b/app/views/ad_api/view_make_report.html.erb @@ -0,0 +1,2 @@ +

AdApi#view

+

Find me in app/views/ad_api/view.html.erb

diff --git a/config/routes.rb b/config/routes.rb index 4d99a71..49eb81a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true Rails.application.routes.draw do + get '/view' => 'ad_api#get_ads' + get '/click' => 'ad_api#update_clicks' resources :ad - # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end diff --git a/db/migrate/20190528085221_create_ads.rb b/db/migrate/20190528085221_create_ads.rb index d76d3d3..03e4ae9 100644 --- a/db/migrate/20190528085221_create_ads.rb +++ b/db/migrate/20190528085221_create_ads.rb @@ -2,9 +2,9 @@ class CreateAds < ActiveRecord::Migration[5.2] def change create_table :ads do |t| - t.integer :advertiser_id, null: false, default: 0 # 広告主ID + t.integer :advertiser_id, null: false # 広告主ID t.string :image, null: false, default: '' # 広告の画像URL - t.integer :price, null: false, default: 0 # 広告の価格 + t.integer :price, null: false # 広告の価格 t.string :text, null: false, default: '' # 広告の説明文 t.timestamps diff --git a/db/migrate/20190604073026_add_report_column_to_ads.rb b/db/migrate/20190604073026_add_report_column_to_ads.rb deleted file mode 100644 index bf8d75f..0000000 --- a/db/migrate/20190604073026_add_report_column_to_ads.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -class AddReportColumnToAds < ActiveRecord::Migration[5.2] - def change - add_column :ads, :click, :integer - add_column :ads, :imp, :integer - add_column :ads, :cv, :integer - end -end diff --git a/db/migrate/20190614041856_create_repos.rb b/db/migrate/20190614041856_create_repos.rb new file mode 100644 index 0000000..3e1ddf2 --- /dev/null +++ b/db/migrate/20190614041856_create_repos.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +class CreateRepos < ActiveRecord::Migration[5.2] + def change + create_table :reports do |t| + t.integer :ad_id, null: false + t.integer :adspot_id, null: false + t.integer :click, null: false, default: 0 + t.integer :imp, null: false, default: 0 + t.integer :cv, null: false, default: 0 + t.integer :price, null: false, default: 0 + t.date :date, null: false, unique: true + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d6923dc..f78b812 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,16 +11,25 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_06_04_073026) do +ActiveRecord::Schema.define(version: 2019_06_14_041856) do create_table 'ads', force: :cascade do |t| - t.integer 'advertiser_id', default: 0, null: false + t.integer 'advertiser_id', null: false t.string 'image', default: '', null: false - t.integer 'price', default: 0, null: false + t.integer 'price', null: false t.string 'text', default: '', null: false t.datetime 'created_at', null: false t.datetime 'updated_at', null: false - t.integer 'click' - t.integer 'imp' - t.integer 'cv' + end + + create_table 'reports', force: :cascade do |t| + t.integer 'ad_id', null: false + t.integer 'adspot_id', null: false + t.integer 'click', default: 0, null: false + t.integer 'imp', default: 0, null: false + t.integer 'cv', default: 0, null: false + t.integer 'price', default: 0, null: false + t.date 'date', null: false + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false end end diff --git a/public/media.site.htm b/public/media.site.htm new file mode 100644 index 0000000..43a7aec --- /dev/null +++ b/public/media.site.htm @@ -0,0 +1,58 @@ + + + + 媒体TEST + + + + +
+ +
+ + + diff --git a/public/uploads/ad/image/2/bg_topicon_p04.png b/public/uploads/ad/image/2/bg_topicon_p04.png new file mode 100644 index 0000000..a773d0a Binary files /dev/null and b/public/uploads/ad/image/2/bg_topicon_p04.png differ diff --git a/spec/controllers/ad_api_controller_spec.rb b/spec/controllers/ad_api_controller_spec.rb new file mode 100644 index 0000000..310f5b0 --- /dev/null +++ b/spec/controllers/ad_api_controller_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true +require 'rails_helper' + +RSpec.describe AdApiController, type: :controller do + before do + @ad1 = FactoryBot.create(:ad) + end + + describe 'GET #get_ads' do + it 'returns http success with valid params' do + get :get_ads, params: { adspot_id: 1, count: 1 } + expect(response).to have_http_status(:success) + end + + describe 'Report' do + it 'an ad should be recorded' do + expect { get :get_ads, params: { adspot_id: 1, count: 1 } }.to change(Report, :count).by(1) + end + + it "record 'imp' should be increased" do + get :get_ads, params: { adspot_id: 1, count: 1 } + report = Report.find_by(ad_id: @ad1.id, adspot_id: 1, date: Date.today) + expect(report.imp).to eq 1 + end + + it "an ad shouldn't be recorded twice from the same adspot_id on the same day" do + get :get_ads, params: { adspot_id: 100, count: 1 } + expect { get :get_ads, params: { adspot_id: 100, count: 1 } }.to change(Report, :count).by(0) + end + + it 'an ad should be recorded from other adspots' do + get :get_ads, params: { adspot_id: 100, count: 1 } + expect { get :get_ads, params: { adspot_id: 101, count: 1 } }.to change(Report, :count).from(1).to(2) + end + + it 'ads should be recorded at the same time' do + ad2 = FactoryBot.create(:ad) + expect { get :get_ads, params: { adspot_id: 101, count: 2 } }.to change(Report, :count).from(0).to(2) + end + + it 'an ad should be recorded on the other day' do + get :get_ads, params: { adspot_id: 101, count: 1 } + travel 1.day do + expect { get :get_ads, params: { adspot_id: 101, count: 1 } }.to change(Report, :count).from(1).to(2) + end + end + + context 'when many ads are requested' do + it 'all ads should be visible ' do + @ad2 = FactoryBot.create(:ad) + @ad3 = FactoryBot.create(:ad) + get :get_ads, params: { adspot_id: 1, count: 3 } + jsons = JSON.parse(response.body) + + ad1_ispresent = false + ad2_ispresent = false + ad3_ispresent = false + + jsons.each do |json| + if json['ad_id'] == @ad1.id + ad1_ispresent = true + elsif json['ad_id'] == @ad2.id + ad2_ispresent = true + elsif json['ad_id'] == @ad3.id + ad3_ispresent = true + end + end + expect(ad1_ispresent).to be_truthy + expect(ad2_ispresent).to be_truthy + expect(ad3_ispresent).to be_truthy + end + end + end + end + + describe 'GET #update_clicks' do + before do + @ad = FactoryBot.create(:ad) + get :get_ads, params: { adspot_id: 1, count: 1 } + end + + it 'returns http success' do + get :update_clicks, params: { ad_id: @ad.id, adspot_id: 1 } + expect(response).to have_http_status(:success) + end + + describe 'Report' do + it 'an ad should be recorded ' do + expect { get :update_clicks, params: { ad_id: @ad.id, adspot_id: 1 } }.to change(Report, :count).by(0) + end + end + end +end diff --git a/spec/controllers/ad_controller_spec.rb b/spec/controllers/ad_controller_spec.rb index f8471fd..59b89a3 100644 --- a/spec/controllers/ad_controller_spec.rb +++ b/spec/controllers/ad_controller_spec.rb @@ -97,7 +97,7 @@ context 'when something empty' do it 'without text should be rendered' do - patch :update, params: { ad: { 'text' =>nil }, id: @ad.id } + patch :update, params: { ad: { 'text' => nil }, id: @ad.id } expect(response).to render_template :edit end diff --git a/spec/factories/ads.rb b/spec/factories/ads.rb index 7ed619b..747dd8f 100644 --- a/spec/factories/ads.rb +++ b/spec/factories/ads.rb @@ -3,7 +3,7 @@ factory :ad do advertiser_id { 1 } image { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec/fixture/image.jpg')) } - price { 222 } + price { 1 } text { 'Test Text' } end end diff --git a/spec/helpers/ad_api_helper_spec.rb b/spec/helpers/ad_api_helper_spec.rb new file mode 100644 index 0000000..20cc2b8 --- /dev/null +++ b/spec/helpers/ad_api_helper_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the AdApiHelper. For example: +# +# describe AdApiHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe AdApiHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/repo_spec.rb b/spec/models/repo_spec.rb new file mode 100644 index 0000000..78f2552 --- /dev/null +++ b/spec/models/repo_spec.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +require 'rails_helper' + +RSpec.describe Report, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e289dbf..b773da3 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -34,6 +34,7 @@ RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" + config.include ActiveSupport::Testing::TimeHelpers # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false diff --git a/spec/views/ad_api/click.html.erb_spec.rb b/spec/views/ad_api/click.html.erb_spec.rb new file mode 100644 index 0000000..f260b75 --- /dev/null +++ b/spec/views/ad_api/click.html.erb_spec.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +require 'rails_helper' + +RSpec.describe 'ad_api/click.html.erb', type: :view do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/views/ad_api/view.html.erb_spec.rb b/spec/views/ad_api/view.html.erb_spec.rb new file mode 100644 index 0000000..a58d59a --- /dev/null +++ b/spec/views/ad_api/view.html.erb_spec.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +require 'rails_helper' + +RSpec.describe 'ad_api/view.html.erb', type: :view do + pending "add some examples to (or delete) #{__FILE__}" +end