Skip to content

Commit

Permalink
refactor logic of keywords into a view-based model.
Browse files Browse the repository at this point in the history
  • Loading branch information
manxingxing committed Nov 17, 2013
1 parent e0e50ec commit bc0b268
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 41 deletions.
2 changes: 1 addition & 1 deletion app/controllers/pages_controller.rb
Expand Up @@ -43,7 +43,7 @@ def imprint
# This provide a first look to our metadata and give a hint about our data
def data
validate_sort_params
@tags = Dataset.tag_counts.order("tags.name")
@tags = DatasetTag.tag_counts
@datasets = Dataset.joins_datafile_and_freeformats(params[:workbook]).select("datasets.id, title,
GREATEST(datasets.updated_at, max(freeformats.updated_at)) as last_update,
count(datafiles.id)").order("#{params[:sort]} #{params[:direction]}")
Expand Down
10 changes: 7 additions & 3 deletions app/controllers/tags_controller.rb
Expand Up @@ -9,7 +9,8 @@ class TagsController < ApplicationController
end

def index
@tags = Dataset.tag_counts.where("name iLike ?", "%#{params[:q]}%").order("tags.name")
@tags = DatasetTag.tag_counts.where("name iLike ?", "%#{params[:q]}%")

respond_to do |format|
format.html
format.json { render :json => @tags}
Expand All @@ -19,7 +20,10 @@ def index

def show
@tag = ActsAsTaggableOn::Tag.find(params[:id])
@datasets = Dataset.tag_usage.select("datasets.*").where("tags.id = ?", @tag.id).order("datasets.title")
@datasets = Dataset.joins(:dataset_tags)
.select("datasets.id, title")
.where(['dataset_tags.tag_id = ?', @tag.id])
.order("lower(datasets.title)")

respond_to do |format|
format.html
Expand All @@ -30,7 +34,7 @@ def show
end

def manage
@all_tags = Dataset.tag_counts.where("name iLike ?", "%#{params[:search]}%").order("tags.name")
@all_tags = DatasetTag.tag_counts
end

def delete
Expand Down
42 changes: 10 additions & 32 deletions app/models/dataset.rb
Expand Up @@ -54,6 +54,9 @@ class Dataset < ActiveRecord::Base
has_many :paperproposals, :through => :dataset_paperproposals
has_many :proposers, :through => :paperproposals, :source => :author, :uniq => true

has_many :dataset_tags
has_many :all_tags, :through => :dataset_tags, :source => :tag, :order => 'lower(name)'

validates :title, :presence => true, :uniqueness => { case_sensitive: false }
ACCESS_CODES = {
private: 0,
Expand Down Expand Up @@ -258,43 +261,18 @@ def to_csv (separate_category_columns = false)
end
end

def all_tags
Dataset.tag_usage.select("tags.*").where("dataset_id = #{self.id}").order("tags.name")
end

# This method returns similar datasets which are sorted by similarity in descending order
# This method returns similar datasets which share keywords with current dataset.
# datasets are sorted by similarity in descending order
def find_related_datasets
tags = self.all_tags.map(&:id)
tags = self.all_tags.pluck(:id)
return [] if tags.empty?
datasets = Dataset.tag_usage.select("datasets.*,count(tags.*) as count").
where(["tags.id in (?) and datasets.id <> ?", tags, self.id]).
group("datasets.id").order("count(tags.*) desc")
datasets = Dataset.joins(:dataset_tags)
.select("datasets.*, count(tag_id) as count")
.where(["tag_id in (?) and datasets.id <> ?", tags, self.id])
.group("datasets.id").order("count(tag_id) desc")
return(datasets)
end

def self.tag_counts
Dataset.tag_usage.select("tags.*, count(datasets.id) as count").group("tags.id")
end
def self.tag_usage
# Return a ActiveRecord::Relation object that can be reused by other methods
Dataset.joins("
join
(
select taggable_id as dataset_id, tag_id
from taggings
where taggable_type = 'Dataset'
union
select distinct d.dataset_id, g.tag_id
from taggings g join datacolumns d
on g.taggable_id = d.id
where g.taggable_type = 'Datacolumn'
) c
on datasets.id = c.dataset_id
join tags
on tags.id = c.tag_id
")
end

def self.joins_datafile_and_freeformats(workbook = nil)
rel = self.joins("
left join freeformats on freeformats.freeformattable_id = datasets.id AND freeformats.freeformattable_type='Dataset'
Expand Down
15 changes: 15 additions & 0 deletions app/models/dataset_tag.rb
@@ -0,0 +1,15 @@
# This is a view-based model
# The view is defined in migration file: 20131116163151_create_dataset_tags_view.rb
# More info about view-based model can be found in Chapter 11 in book 'Enterprise Rails'.

class DatasetTag < ActiveRecord::Base
belongs_to :dataset
belongs_to :tag, class_name: 'ActsAsTaggableOn::Tag'

def self.tag_counts
ActsAsTaggableOn::Tag.joins('left join dataset_tags on tags.id = dataset_tags.tag_id')
.select('tags.*, count(dataset_id) as count')
.group('tags.id')
.order('lower(tags.name)')
end
end
2 changes: 1 addition & 1 deletion app/models/user.rb
Expand Up @@ -141,7 +141,7 @@ def change_avatar_file_name
end

def add_protocol_to_url
unless self.url.blank?
if self.url.present? and self.url_changed?
/^http/.match(self.url) ? self.url : self.url = "http://#{url}"
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/workbook.rb
Expand Up @@ -155,7 +155,7 @@ def datemax
date_string.to_i > 2000 ? Date.new(date_string.to_i) : Date.today
end

# This generate a hash in form of {header: columnnr}. columnnr is 0-based
# This generate a hash in form of {header: columnnr}. columnnr is 0-based.
# When a column is saved later, its info will be stored into values.
# then, this hash becomes {header: [columnnr, datacolumn_id, data_type_id]}
def header_info_lookup
Expand Down
2 changes: 1 addition & 1 deletion app/views/datasets/show.html.haml
Expand Up @@ -16,7 +16,7 @@
- content_for :info do
- unless @tags.blank?
%h3= link_to "Keywords", keywords_dataset_path(@dataset)
= raw @tags.sort_by(&:name).map{|t| link_to t.name, keyword_path(t.id)}.join(", ")
= raw @tags.map{|t| link_to t.name, keyword_path(t.id)}.join(", ")

%h3
Last update
Expand Down
23 changes: 23 additions & 0 deletions db/migrate/20131116163151_create_dataset_tags_view.rb
@@ -0,0 +1,23 @@
class CreateDatasetTagsView < ActiveRecord::Migration
def up
execute <<-SQL
CREATE OR REPLACE view dataset_tags AS
(
select taggable_id as dataset_id, tag_id
from taggings
where taggable_type = 'Dataset'
union
select distinct d.dataset_id, g.tag_id
from taggings g join datacolumns d
on g.taggable_id = d.id
where g.taggable_type = 'Datacolumn'
);
SQL
end

def down
execute <<-SQL
drop view dataset_tags;
SQL
end
end
19 changes: 18 additions & 1 deletion db/non_schema_sql.sql
Expand Up @@ -171,4 +171,21 @@ CREATE OR REPLACE FUNCTION update_date_category_datasets(category_id integer) RE
set updated_at = now()
from sheetcells sc inner join datacolumns dc on sc.datacolumn_id = dc.id
where category_id = $1 and datasets.id = dc.dataset_id
returning true$_$;
returning true$_$;



--
--- Define a view
--
CREATE OR REPLACE view dataset_tags AS
(
select taggable_id as dataset_id, tag_id
from taggings
where taggable_type = 'Dataset'
union
select distinct d.dataset_id, g.tag_id
from taggings g join datacolumns d
on g.taggable_id = d.id
where g.taggable_type = 'Datacolumn'
);
2 changes: 1 addition & 1 deletion db/schema.rb
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20131111135126) do
ActiveRecord::Schema.define(:version => 20131116163151) do

create_table "author_paperproposals", :force => true do |t|
t.integer "paperproposal_id"
Expand Down

0 comments on commit bc0b268

Please sign in to comment.