aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/public_body_controller.rb18
-rw-r--r--app/models/public_body.rb3
-rw-r--r--app/models/public_body_tag.rb48
-rw-r--r--db/migrate/093_move_to_has_tag_string.rb23
-rw-r--r--db/schema.rb24
-rw-r--r--spec/models/has_tag_string_tag_spec.rb (renamed from spec/models/public_body_tag_spec.rb)2
-rw-r--r--todo.txt4
-rw-r--r--vendor/plugins/has_tag_string/lib/has_tag_string.rb93
8 files changed, 124 insertions, 91 deletions
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb
index 5f51948ee..560206900 100644
--- a/app/controllers/public_body_controller.rb
+++ b/app/controllers/public_body_controller.rb
@@ -65,24 +65,28 @@ class PublicBodyController < ApplicationController
end
def list
+ # XXX move some of these tag SQL queries into has_tag_string.rb
@tag = params[:tag]
if @tag.nil?
@tag = "all"
conditions = []
elsif @tag == 'other'
category_list = PublicBodyCategories::CATEGORIES.map{|c| "'"+c+"'"}.join(",")
- conditions = ['(select count(*) from public_body_tags where public_body_tags.public_body_id = public_bodies.id
- and public_body_tags.name in (' + category_list + ')) = 0']
+ conditions = ['(select count(*) from has_tag_string_tags where has_tag_string_tags.model_id = public_bodies.id
+ and has_tag_string_tags.model = \'PublicBody\'
+ and has_tag_string_tags.name in (' + category_list + ')) = 0']
elsif @tag.size == 1
@tag.upcase!
conditions = ['first_letter = ?', @tag]
elsif @tag.include?(":")
- name, value = PublicBodyTag.split_tag_into_name_value(@tag)
- conditions = ['(select count(*) from public_body_tags where public_body_tags.public_body_id = public_bodies.id
- and public_body_tags.name = ? and public_body_tags.value = ?) > 0', name, value]
+ name, value = HasTagString::HasTagStringTag.split_tag_into_name_value(@tag)
+ conditions = ['(select count(*) from has_tag_string_tags where has_tag_string_tags.model_id = public_bodies.id
+ and has_tag_string_tags.model = \'PublicBody\'
+ and has_tag_string_tags.name = ? and has_tag_string_tags.value = ?) > 0', name, value]
else
- conditions = ['(select count(*) from public_body_tags where public_body_tags.public_body_id = public_bodies.id
- and public_body_tags.name = ?) > 0', @tag]
+ conditions = ['(select count(*) from has_tag_string_tags where has_tag_string_tags.model_id = public_bodies.id
+ and has_tag_string_tags.model = \'PublicBody\'
+ and has_tag_string_tags.name = ?) > 0', @tag]
end
@public_bodies = PublicBody.paginate(
:order => "public_bodies.name", :page => params[:page], :per_page => 1000, # fit all councils on one page
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 491ffe989..1bd9dcc94 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -42,7 +42,6 @@ class PublicBody < ActiveRecord::Base
has_many :info_requests, :order => 'created_at desc'
has_many :track_things, :order => 'created_at desc'
- has_many :public_body_tags
has_tag_string
# like find_by_url_name but also search historic url_name if none found
@@ -190,7 +189,7 @@ class PublicBody < ActiveRecord::Base
def type_of_authority(html = false)
types = []
first = true
- for tag in self.public_body_tags
+ for tag in self.tags
if PublicBodyCategories::CATEGORIES_BY_TAG.include?(tag.name)
desc = PublicBodyCategories::CATEGORY_SINGULAR_BY_TAG[tag.name]
if first
diff --git a/app/models/public_body_tag.rb b/app/models/public_body_tag.rb
deleted file mode 100644
index e24ace7d7..000000000
--- a/app/models/public_body_tag.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# == Schema Information
-# Schema version: 92
-#
-# Table name: public_body_tags
-#
-# id :integer not null, primary key
-# public_body_id :integer not null
-# name :text not null
-# created_at :datetime not null
-# value :text
-#
-
-# models/public_body_tag.rb:
-# Categories for public bodies.
-#
-# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved.
-# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
-#
-# $Id: public_body_tag.rb,v 1.29 2009-09-17 21:10:05 francis Exp $
-
-class PublicBodyTag < ActiveRecord::Base
- strip_attributes!
-
- validates_presence_of :public_body
- validates_presence_of :name
-
- belongs_to :public_body
-
- def name_and_value
- ret = self.name
- if !self.value.nil?
- ret += ":" + self.value
- end
- return ret
- end
-
- def PublicBodyTag.split_tag_into_name_value(tag)
- sections = tag.split(/:/)
- name = sections[0]
- if sections[1]
- value = sections[1,sections.size].join(":")
- else
- value = nil
- end
- return name, value
- end
-end
-
diff --git a/db/migrate/093_move_to_has_tag_string.rb b/db/migrate/093_move_to_has_tag_string.rb
new file mode 100644
index 000000000..58f36c224
--- /dev/null
+++ b/db/migrate/093_move_to_has_tag_string.rb
@@ -0,0 +1,23 @@
+class MoveToHasTagString < ActiveRecord::Migration
+ def self.up
+ rename_table :public_body_tags, :has_tag_string_tags
+
+ # we rename existing column:
+ rename_column :has_tag_string_tags, :public_body_id, :model_id
+ # if using has_tag_string afresh in another project, can use this:
+ # add_column :has_tag_string_tags, :model_id, :integer, :null => false
+
+ # the model needs a default value, so build in stages:
+ add_column :has_tag_string_tags, :model, :string
+ HasTagString::HasTagStringTag.update_all "model = 'PublicBody'"
+ change_column :has_tag_string_tags, :model, :string, :null => false
+ # just use this for a fresh project:
+ # add_column :has_tag_string_tags, :model, :string, :null => false
+
+ add_index :has_tag_string_tags, [:model, :model_id]
+ end
+
+ def self.down
+ raise "no reverse migration"
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0c90be6b1..6df97a137 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 92) do
+ActiveRecord::Schema.define(:version => 93) do
create_table "acts_as_xapian_jobs", :force => true do |t|
t.string "model", :null => false
@@ -65,6 +65,18 @@ ActiveRecord::Schema.define(:version => 92) do
add_index "exim_logs", ["exim_log_done_id"], :name => "index_exim_logs_on_exim_log_done_id"
+ create_table "has_tag_string_tags", :force => true do |t|
+ t.integer "model_id", :null => false
+ t.text "name", :null => false
+ t.datetime "created_at", :null => false
+ t.text "value"
+ t.string "model", :null => false
+ end
+
+ add_index "has_tag_string_tags", ["model", "model_id"], :name => "index_has_tag_string_tags_on_model_and_model_id"
+ add_index "has_tag_string_tags", ["model_id", "name", "value"], :name => "index_public_body_tags_on_public_body_id_and_name_and_value", :unique => true
+ add_index "has_tag_string_tags", ["name"], :name => "index_public_body_tags_on_name"
+
create_table "holidays", :force => true do |t|
t.date "day"
t.text "description"
@@ -173,16 +185,6 @@ ActiveRecord::Schema.define(:version => 92) do
add_index "public_bodies", ["first_letter"], :name => "index_public_bodies_on_first_letter"
add_index "public_bodies", ["url_name"], :name => "index_public_bodies_on_url_name", :unique => true
- create_table "public_body_tags", :force => true do |t|
- t.integer "public_body_id", :null => false
- t.text "name", :null => false
- t.datetime "created_at", :null => false
- t.text "value"
- end
-
- add_index "public_body_tags", ["name", "public_body_id", "value"], :name => "index_public_body_tags_on_public_body_id_and_name_and_value", :unique => true
- add_index "public_body_tags", ["name"], :name => "index_public_body_tags_on_name"
-
create_table "public_body_versions", :force => true do |t|
t.integer "public_body_id"
t.integer "version"
diff --git a/spec/models/public_body_tag_spec.rb b/spec/models/has_tag_string_tag_spec.rb
index 09a597bd0..c85f64b14 100644
--- a/spec/models/public_body_tag_spec.rb
+++ b/spec/models/has_tag_string_tag_spec.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-describe PublicBodyTag, " when fiddling with public body tags " do
+describe PublicBodyTag, " when fiddling with tag strings " do
fixtures :public_bodies
it "should be able to make a new tag and save it" do
diff --git a/todo.txt b/todo.txt
index a9f640a69..883f83b5b 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,3 +1,7 @@
+PublicBodyTag
+public_body_tags
+
+
Next (things that will reduce admin time mainly)
====
diff --git a/vendor/plugins/has_tag_string/lib/has_tag_string.rb b/vendor/plugins/has_tag_string/lib/has_tag_string.rb
index ca147ba27..b13803d23 100644
--- a/vendor/plugins/has_tag_string/lib/has_tag_string.rb
+++ b/vendor/plugins/has_tag_string/lib/has_tag_string.rb
@@ -1,5 +1,5 @@
# lib/has_tag_string.rb:
-# Lets a model have tags, represented as space separate strings in a public #
+# Lets a model have tags, represented as space separate strings in a public
# interface, but stored in the database as keys. Each tag can have a value
# followed by a colon - e.g. url:http://www.flourish.org
#
@@ -7,6 +7,39 @@
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
module HasTagString
+ # Represents one tag of one model.
+ # The migration to make this is currently only in WDTK code.
+ class HasTagStringTag < ActiveRecord::Base
+ # XXX strip_attributes!
+
+ validates_presence_of :name
+
+ # Return instance of the model that this tag tags
+ def tagged_model
+ return self.model.constantize.find(self.model_id)
+ end
+
+ def name_and_value
+ ret = self.name
+ if !self.value.nil?
+ ret += ":" + self.value
+ end
+ return ret
+ end
+
+ def HasTagStringTag.split_tag_into_name_value(tag)
+ sections = tag.split(/:/)
+ name = sections[0]
+ if sections[1]
+ value = sections[1,sections.size].join(":")
+ else
+ value = nil
+ end
+ return name, value
+ end
+ end
+
+ # Methods which are added to the model instances being tagged
module InstanceMethods
# Given an input string of tags, sets all tags to that string.
# XXX This immediately saves the new tags.
@@ -16,41 +49,51 @@ module HasTagString
tags = tag_string.split(/\s+/).uniq
ActiveRecord::Base.transaction do
- for public_body_tag in self.public_body_tags
- public_body_tag.destroy
+ for tag in self.tags
+ tag.destroy
end
- self.public_body_tags = []
+ self.tags = []
for tag in tags
# see if is a machine tags (i.e. a tag which has a value)
- name, value = PublicBodyTag.split_tag_into_name_value(tag)
+ name, value = HasTagStringTag.split_tag_into_name_value(tag)
- public_body_tag = PublicBodyTag.new(:name => name, :value => value)
- self.public_body_tags << public_body_tag
- public_body_tag.public_body = self
+ tag = HasTagStringTag.new(
+ :model => self.class.base_class.to_s,
+ :model_id => self.id,
+ :name => name, :value => value
+ )
+ self.tags << tag
end
end
end
+
+ # Returns the tags the model has, as a space separated string
def tag_string
- return self.public_body_tags.map { |t| t.name_and_value }.join(' ')
+ return self.tags.map { |t| t.name_and_value }.join(' ')
end
- def has_tag?(tag)
- for public_body_tag in self.public_body_tags
- if public_body_tag.name == tag
+
+ # Test to see if class is tagged with the given tag
+ def has_tag?(tag_as_string)
+ for tag in self.tags
+ if tag.name == tag_as_string
return true
end
end
return false
end
+
class TagNotFound < StandardError
end
- def get_tag_values(tag)
+
+ # If the tag is a machine tag, returns array of its values
+ def get_tag_values(tag_as_string)
found = false
results = []
- for public_body_tag in self.public_body_tags
- if public_body_tag.name == tag
+ for tag in self.tags
+ if tag.name == tag_as_string
found = true
- if !public_body_tag.value.nil?
- results << public_body_tag.value
+ if !tag.value.nil?
+ results << tag.value
end
end
end
@@ -59,16 +102,20 @@ module HasTagString
end
return results
end
- def add_tag_if_not_already_present(tag)
- self.tag_string = self.tag_string + " " + tag
- end
+ # Adds a new tag to the model, if it isn't already there
+ def add_tag_if_not_already_present(tag_as_string)
+ self.tag_string = self.tag_string + " " + tag_as_string
+ end
end
+ # Methods which are added to the model class being tagged
module ClassMethods
# Find all public bodies with a particular tag
- def find_by_tag(tag)
- return PublicBodyTag.find(:all, :conditions => ['name = ?', tag] ).map { |t| t.public_body }.sort { |a,b| a.name <=> b.name }
+ def find_by_tag(tag_as_string)
+ return HasTagStringTag.find(:all, :conditions =>
+ ['name = ? and model = ?', tag_as_string, self.to_s ]
+ ).map { |t| t.tagged_model }.sort { |a,b| a.name <=> b.name }
end
end
@@ -76,6 +123,8 @@ module HasTagString
# Main entry point, add has_tag_string to your model.
module HasMethods
def has_tag_string()
+ has_many :tags, :conditions => "model = '" + self.to_s + "'", :foreign_key => "model_id", :class_name => 'HasTagString::HasTagStringTag'
+
include InstanceMethods
self.class.send :include, ClassMethods
end