From 3c57de4ae1878ad082a8cdfcfdaeddef82a3627f Mon Sep 17 00:00:00 2001
From: Sybil <sybil.deboin@gmail.com>
Date: Fri, 19 Dec 2014 21:12:50 +0100
Subject: [PATCH] O.K. : Tracks contain every useful data.  - Tags weren't
 displayed. Solution : composite_primary_keys gem to manage the shi***
 database design.  - Json unreadable. Solution : active_model_serializers to
 select json fields.  - SQL requests too slow. Solution : includes in place of
 joins (3x faster).  PS : TY Zar.

---
 Gemfile                                   | 11 +++++++++--
 Gemfile.lock                              | 23 ++++++++++++-----------
 app/controllers/application_controller.rb |  3 +--
 app/controllers/channels_controller.rb    |  4 ++--
 app/controllers/musics_controller.rb      | 23 -----------------------
 app/controllers/tags_controller.rb        |  2 +-
 app/controllers/tracks_controller.rb      | 22 ++++++++++++++++++++++
 app/models/channel.rb                     |  2 +-
 app/models/music.rb                       | 20 --------------------
 app/models/tag.rb                         |  6 ++++--
 app/models/track.rb                       | 22 ++++++++++++++++++++++
 app/serializers/channel_serializer.rb     |  4 ++++
 app/serializers/tag_serializer.rb         |  5 +++++
 app/serializers/track_serializer.rb       |  7 +++++++
 config/application.rb                     |  8 ++++++++
 config/routes.rb                          | 18 ++++++++----------
 16 files changed, 106 insertions(+), 74 deletions(-)
 delete mode 100644 app/controllers/musics_controller.rb
 create mode 100644 app/controllers/tracks_controller.rb
 delete mode 100644 app/models/music.rb
 create mode 100644 app/models/track.rb
 create mode 100644 app/serializers/channel_serializer.rb
 create mode 100644 app/serializers/tag_serializer.rb
 create mode 100644 app/serializers/track_serializer.rb

diff --git a/Gemfile b/Gemfile
index 5320d81..5266eef 100644
--- a/Gemfile
+++ b/Gemfile
@@ -16,11 +16,18 @@ gem 'rails', '4.1.5'
 
 #Gem to produce a lightweight json API
 gem 'rails-api'
+#Authorize API usage from different domains
+gem 'rack-cors'
+#Add Serializer class to choose json fields
+gem 'active_model_serializers'
+#Because we're using a shitty database designed by a fuckin' drug addict
+gem 'composite_primary_keys'
 
 # Use jquery as the JavaScript library
 #gem 'jquery-rails'
+
 # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
-gem 'turbolinks'
+# gem 'turbolinks'
 # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
 gem 'jbuilder', '~> 2.0'
 # bundle exec rake doc:rails generates the API under doc/api.
@@ -36,7 +43,7 @@ gem 'mysql2'
 #gem 'soundcloud'
 
 #Gem for pagination
-#gem 'kaminari'
+gem 'kaminari'
 
 #Gem for Ruby web server
 gem 'thin'
diff --git a/Gemfile.lock b/Gemfile.lock
index a727228..a544130 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -14,6 +14,8 @@ GEM
       activesupport (= 4.1.5)
       builder (~> 3.1)
       erubis (~> 2.7.0)
+    active_model_serializers (0.9.2)
+      activemodel (>= 3.2)
     activemodel (4.1.5)
       activesupport (= 4.1.5)
       builder (~> 3.1)
@@ -30,23 +32,20 @@ GEM
     arel (5.0.1.20140414130214)
     builder (3.2.2)
     coderay (1.1.0)
-    coffee-rails (4.0.1)
-      coffee-script (>= 2.2.0)
-      railties (>= 4.0.0, < 5.0)
-    coffee-script (2.3.0)
-      coffee-script-source
-      execjs
-    coffee-script-source (1.7.1)
+    composite_primary_keys (7.0.10)
+      activerecord (~> 4.1.4)
     daemons (1.1.9)
     erubis (2.7.0)
     eventmachine (1.0.3)
-    execjs (2.2.1)
     hike (1.2.3)
     i18n (0.6.11)
     jbuilder (2.1.3)
       activesupport (>= 3.0.0, < 5)
       multi_json (~> 1.2)
     json (1.8.1)
+    kaminari (0.16.1)
+      actionpack (>= 3.0.0)
+      activesupport (>= 3.0.0)
     mail (2.5.4)
       mime-types (~> 1.16)
       treetop (~> 1.4.8)
@@ -61,6 +60,7 @@ GEM
       method_source (~> 0.8.1)
       slop (~> 3.4)
     rack (1.5.2)
+    rack-cors (0.2.9)
     rack-test (0.6.2)
       rack (>= 1.0)
     rails (4.1.5)
@@ -108,8 +108,6 @@ GEM
     treetop (1.4.15)
       polyglot
       polyglot (>= 0.3.1)
-    turbolinks (2.3.0)
-      coffee-rails
     tzinfo (1.2.2)
       thread_safe (~> 0.1)
 
@@ -117,12 +115,15 @@ PLATFORMS
   ruby
 
 DEPENDENCIES
+  active_model_serializers
+  composite_primary_keys
   jbuilder (~> 2.0)
+  kaminari
   mysql2
   pry
+  rack-cors
   rails (= 4.1.5)
   rails-api
   sdoc (~> 0.4.0)
   spring
   thin
-  turbolinks
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 28f326e..6d7c870 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,6 +1,5 @@
 class ApplicationController < ActionController::API
-  # Prevent CSRF attacks by raising an exception.
-  # For APIs, you may want to use :null_session instead.
+  include ActionController::Serialization
 
   before_filter :get_tags, :get_users, :get_channels
 
diff --git a/app/controllers/channels_controller.rb b/app/controllers/channels_controller.rb
index 997639b..661eb72 100644
--- a/app/controllers/channels_controller.rb
+++ b/app/controllers/channels_controller.rb
@@ -10,12 +10,12 @@ class ChannelsController < ApplicationController
   end
 
   def show_user
-    @musics = Music.joins(:channel).where(playbot_chan: {sender_irc: params[:user]})
+    @tracks = Track.joins(:channel).where(playbot_chan: {sender_irc: params[:user]})
     render json: @user, status: 200
   end
 
   def show_channel
-    @musics = Music.joins(:channel).where(playbot_chan: {chan: "#"+params[:channel]})
+    @tracks = Track.joins(:channel).where(playbot_chan: {chan: "#"+params[:channel]})
     render json: @channel, status:200
   end
 
diff --git a/app/controllers/musics_controller.rb b/app/controllers/musics_controller.rb
deleted file mode 100644
index 8ec3981..0000000
--- a/app/controllers/musics_controller.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class MusicsController < ApplicationController
-  def filters( *filters )
-    filters.each do | filter |
-      if param = params[filter] || params["#{filter}_id"]
-        @musics = @musics.send( "with_#{filter}", param )
-      end
-    end
-  end
-
-  def index
-    @musics = Music.all
-    filters :tag, :channel, :user
-  
-    render json: @musics, status: 200
-  end
-
-  def show 
-    @music = Music.find(params[:id])
-    
-    render json: @music, status: 200
-  end
-
-end
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 61e6cc4..8a4bc95 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -5,7 +5,7 @@ class TagsController < ApplicationController
   end
 
   def show
-    @musics = Music.joins(:tags).where(playbot_tags: {tag: params[:tag]})
+    @tracks = Track.joins(:tags).where(playbot_tags: {tag: params[:tag]})
     render json: @tag, status: 200
   end
 end
diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb
new file mode 100644
index 0000000..e56744b
--- /dev/null
+++ b/app/controllers/tracks_controller.rb
@@ -0,0 +1,22 @@
+class TracksController < ApplicationController
+  def filters( *filters )
+    filters.each do | filter |
+      if param = params[filter] || params["#{filter}_id"]
+        @tracks = @tracks.send( "with_#{filter}", param )
+      end
+    end
+  end
+
+  def index
+    @tracks = Track.includes(:channel, :tags)
+    filters :tag, :channel, :user
+    render json: @tracks, status: 200
+  end
+
+  def show 
+    @track = Track.find(params[:id])
+    
+    render json: @track, status: 200
+  end
+
+end
diff --git a/app/models/channel.rb b/app/models/channel.rb
index 9431782..685d2ee 100644
--- a/app/models/channel.rb
+++ b/app/models/channel.rb
@@ -1,6 +1,6 @@
 class Channel < ActiveRecord::Base
   self.table_name = "playbot_chan"
-  belongs_to :music
+  belongs_to :track
 
   def self.with_channel(channel)
     where("chan = ?", channel)
diff --git a/app/models/music.rb b/app/models/music.rb
deleted file mode 100644
index 5d8466b..0000000
--- a/app/models/music.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class Music < ActiveRecord::Base
-  self.table_name = "playbot"
-  self.inheritance_column = "inheritance_type"
-
-  has_many :tags, foreign_key: "id"
-  has_one :channel, primary_key: "id", foreign_key: "content"
-
-  def self.with_tag(tag)
-      self.joins(:tags).where("tag = ?", tag )
-  end
-
-  def self.with_channel(channel)
-    self.joins(:channel).where("chan = ?", "##{channel}")
-  end
-
-  def self.with_user(user)
-    self.joins(:channel).where("playbot_chan.sender_irc = ?", user)
-  end 
-
-end
diff --git a/app/models/tag.rb b/app/models/tag.rb
index f8dce78..2b80e73 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -1,5 +1,7 @@
 class Tag < ActiveRecord::Base
-  self.table_name = "playbot_tags"
-  belongs_to :music
+  self.table_name = :playbot_tags
+  self.primary_keys = :id, :tag
+  
+  belongs_to :track
 
 end
diff --git a/app/models/track.rb b/app/models/track.rb
new file mode 100644
index 0000000..af4dc09
--- /dev/null
+++ b/app/models/track.rb
@@ -0,0 +1,22 @@
+class Track < ActiveRecord::Base
+  self.table_name = :playbot
+  self.inheritance_column = :inheritance_type
+
+  has_many :tags, primary_key: :id, foreign_key: :id
+  has_one :channel, primary_key: :id, foreign_key: :content
+
+  def self.with_tag(tag)
+    self.joins(:tags).where("tag = ?", tag )
+    #self.includes(:tags)
+    #self.where("tag = ?", tag)
+  end
+
+  def self.with_channel(channel)
+    self.joins(:channel).where("chan = ?", "##{channel}")
+  end
+
+  def self.with_user(user)
+    self.joins(:channel).where("playbot_chan.sender_irc = ?", user)
+  end 
+
+end
diff --git a/app/serializers/channel_serializer.rb b/app/serializers/channel_serializer.rb
new file mode 100644
index 0000000..018567a
--- /dev/null
+++ b/app/serializers/channel_serializer.rb
@@ -0,0 +1,4 @@
+class ChannelSerializer < ActiveModel::Serializer
+  attributes :sender_irc, :chan
+
+end
diff --git a/app/serializers/tag_serializer.rb b/app/serializers/tag_serializer.rb
new file mode 100644
index 0000000..11bcf2e
--- /dev/null
+++ b/app/serializers/tag_serializer.rb
@@ -0,0 +1,5 @@
+class TagSerializer < ActiveModel::Serializer
+  attributes :tag
+
+  #belongs_to :track
+end
diff --git a/app/serializers/track_serializer.rb b/app/serializers/track_serializer.rb
new file mode 100644
index 0000000..30265c8
--- /dev/null
+++ b/app/serializers/track_serializer.rb
@@ -0,0 +1,7 @@
+class TrackSerializer < ActiveModel::Serializer
+  attributes :id, :title, :url, :type
+
+  has_one :channel
+  has_many :tags
+
+end
diff --git a/config/application.rb b/config/application.rb
index c8591de..870b2c6 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -24,5 +24,13 @@ module WebPlayBot
     # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
     # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
     # config.i18n.default_locale = :de
+
+    config.middleware.use Rack::Cors do
+      allow do
+        origins '*'
+        resource '*', :headers => :any, :methods => [:get, :post, :options]
+      end
+    end
+
   end
 end
diff --git a/config/routes.rb b/config/routes.rb
index 0b1640f..72f0bb3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,16 +1,14 @@
 Rails.application.routes.draw do
 
-  constraints subdomain: 'api' do
-    get '/users', to: "channels#index_users"
+  get '/users', to: "channels#index_users"
 
-    concern :tracks do
-      resources :musics, only: [:index]
-    end
-    resources :tags, concerns: :tracks, only: [:index, :show]
-    resources :channels, concerns: :tracks, only: [:index, :show]
-    resources :users, concerns: :tracks, only: [:index, :show]
-
-    root to: 'musics#index'
+  concern :tracks do
+    resources :tracks, only: [:index]
   end
+  resources :tags, concerns: :tracks, only: [:index, :show]
+  resources :channels, concerns: :tracks, only: [:index, :show]
+  resources :users, concerns: :tracks, only: [:index, :show]
+  resources :tracks, only: [:index, :show]
 
+  root to: 'tracks#index'
 end
-- 
GitLab