aboutsummaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/public_body.rb14
-rw-r--r--app/models/public_body_category.rb90
-rw-r--r--app/models/public_body_category/category_collection.rb54
-rw-r--r--app/models/public_body_category_link.rb34
-rw-r--r--app/models/public_body_heading.rb75
5 files changed, 260 insertions, 7 deletions
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index 87b5c2227..f61a3f449 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -132,14 +132,14 @@ class PublicBody < ActiveRecord::Base
end
def translated_versions=(translation_attrs)
- def skip?(attrs)
- valueless = attrs.inject({}) { |h, (k, v)| h[k] = v if v != '' and k != 'locale'; h } # because we want to fall back to alternative translations where there are empty values
- return valueless.length == 0
+ def empty_translation?(attrs)
+ attrs_with_values = attrs.select{ |key, value| value != '' and key != 'locale' }
+ attrs_with_values.empty?
end
if translation_attrs.respond_to? :each_value # Hash => updating
translation_attrs.each_value do |attrs|
- next if skip?(attrs)
+ next if empty_translation?(attrs)
t = translation_for(attrs[:locale]) || PublicBody::Translation.new
t.attributes = attrs
calculate_cached_fields(t)
@@ -147,7 +147,7 @@ class PublicBody < ActiveRecord::Base
end
else # Array => creating
translation_attrs.each do |attrs|
- next if skip?(attrs)
+ next if empty_translation?(attrs)
new_translation = PublicBody::Translation.new(attrs)
calculate_cached_fields(new_translation)
translations << new_translation
@@ -335,8 +335,8 @@ class PublicBody < ActiveRecord::Base
types = []
first = true
for tag in self.tags
- if PublicBodyCategories::get().by_tag().include?(tag.name)
- desc = PublicBodyCategories::get().singular_by_tag()[tag.name]
+ if PublicBodyCategory.get().by_tag().include?(tag.name)
+ desc = PublicBodyCategory.get().singular_by_tag()[tag.name]
if first
# terrible that Ruby/Rails doesn't have an equivalent of ucfirst
# (capitalize shockingly converts later characters to lowercase)
diff --git a/app/models/public_body_category.rb b/app/models/public_body_category.rb
new file mode 100644
index 000000000..8eaecd596
--- /dev/null
+++ b/app/models/public_body_category.rb
@@ -0,0 +1,90 @@
+# == Schema Information
+#
+# Table name: public_body_categories
+#
+# id :integer not null, primary key
+# title :text not null
+# category_tag :text not null
+# description :text not null
+# display_order :integer
+#
+
+require 'forwardable'
+
+class PublicBodyCategory < ActiveRecord::Base
+ attr_accessible :locale, :category_tag, :title, :description,
+ :translated_versions, :display_order
+
+ has_many :public_body_category_links, :dependent => :destroy
+ has_many :public_body_headings, :through => :public_body_category_links
+
+ translates :title, :description
+ validates_uniqueness_of :category_tag, :message => N_('Tag is already taken')
+ validates_presence_of :title, :message => N_("Title can't be blank")
+ validates_presence_of :category_tag, :message => N_("Tag can't be blank")
+
+ def self.get
+ locale = I18n.locale.to_s || default_locale.to_s || ""
+ categories = CategoryCollection.new
+ I18n.with_locale(locale) do
+ headings = PublicBodyHeading.all
+ headings.each do |heading|
+ categories << heading.name
+ heading.public_body_categories.each do |category|
+ categories << [
+ category.category_tag,
+ category.title,
+ category.description
+ ]
+ end
+ end
+ end
+ categories
+ end
+
+ def self.without_headings
+ sql = %Q| SELECT * FROM public_body_categories pbc
+ WHERE pbc.id NOT IN (
+ SELECT public_body_category_id AS id
+ FROM public_body_category_links
+ ) |
+ PublicBodyCategory.find_by_sql(sql)
+ end
+
+ # Called from the old-style public_body_categories_[locale].rb data files
+ def self.add(locale, data_list)
+ CategoryAndHeadingMigrator.add_categories_and_headings_from_list(locale, data_list)
+ end
+
+ # Convenience methods for creating/editing translations via forms
+ def find_translation_by_locale(locale)
+ translations.find_by_locale(locale)
+ end
+
+ def translated_versions
+ translations
+ end
+
+ def translated_versions=(translation_attrs)
+ def empty_translation?(attrs)
+ attrs_with_values = attrs.select{ |key, value| value != '' and key != 'locale' }
+ attrs_with_values.empty?
+ end
+ if translation_attrs.respond_to? :each_value # Hash => updating
+ translation_attrs.each_value do |attrs|
+ next if empty_translation?(attrs)
+ t = translation_for(attrs[:locale]) || PublicBodyCategory::Translation.new
+ t.attributes = attrs
+ t.save!
+ end
+ else # Array => creating
+ translation_attrs.each do |attrs|
+ next if empty_translation?(attrs)
+ new_translation = PublicBodyCategory::Translation.new(attrs)
+ translations << new_translation
+ end
+ end
+ end
+end
+
+
diff --git a/app/models/public_body_category/category_collection.rb b/app/models/public_body_category/category_collection.rb
new file mode 100644
index 000000000..8286e2710
--- /dev/null
+++ b/app/models/public_body_category/category_collection.rb
@@ -0,0 +1,54 @@
+# replicate original file-based PublicBodyCategories functionality
+class PublicBodyCategory::CategoryCollection
+ include Enumerable
+ extend Forwardable
+ def_delegators :@categories, :each, :<<
+
+ def initialize
+ @categories = []
+ end
+
+ def with_headings
+ @categories
+ end
+
+ def with_description
+ @categories.select() { |a| a.instance_of?(Array) }
+ end
+
+ def tags
+ tags = with_description.map() { |a| a[0] }
+ end
+
+ def by_tag
+ Hash[*with_description.map() { |a| a[0..1] }.flatten]
+ end
+
+ def singular_by_tag
+ Hash[*with_description.map() { |a| [a[0],a[2]] }.flatten]
+ end
+
+ def by_heading
+ output = {}
+ heading = nil
+ @categories.each do |row|
+ if row.is_a?(Array)
+ output[heading] << row[0]
+ else
+ heading = row
+ output[heading] = []
+ end
+ end
+ output
+ end
+
+ def headings
+ output = []
+ @categories.each do |row|
+ unless row.is_a?(Array)
+ output << row
+ end
+ end
+ output
+ end
+end
diff --git a/app/models/public_body_category_link.rb b/app/models/public_body_category_link.rb
new file mode 100644
index 000000000..eb233b56f
--- /dev/null
+++ b/app/models/public_body_category_link.rb
@@ -0,0 +1,34 @@
+# == Schema Information
+#
+# Table name: public_body_category_link
+#
+# public_body_category_id :integer not null
+# public_body_heading_id :integer not null
+# category_display_order :integer
+#
+
+class PublicBodyCategoryLink < ActiveRecord::Base
+ attr_accessible :public_body_category_id, :public_body_heading_id, :category_display_order
+
+ belongs_to :public_body_category
+ belongs_to :public_body_heading
+ validates_presence_of :public_body_category
+ validates_presence_of :public_body_heading
+ validates :category_display_order, :numericality => { :only_integer => true,
+ :message => N_('Display order must be a number') }
+
+ before_validation :on => :create do
+ unless self.category_display_order
+ self.category_display_order = PublicBodyCategoryLink.next_display_order(public_body_heading_id)
+ end
+ end
+
+ def self.next_display_order(heading_id)
+ if last = where(:public_body_heading_id => heading_id).order(:category_display_order).last
+ last.category_display_order + 1
+ else
+ 0
+ end
+ end
+
+end
diff --git a/app/models/public_body_heading.rb b/app/models/public_body_heading.rb
new file mode 100644
index 000000000..c38800561
--- /dev/null
+++ b/app/models/public_body_heading.rb
@@ -0,0 +1,75 @@
+# == Schema Information
+#
+# Table name: public_body_headings
+#
+# id :integer not null, primary key
+# name :text not null
+# display_order :integer
+#
+
+class PublicBodyHeading < ActiveRecord::Base
+ attr_accessible :name, :display_order, :translated_versions
+
+ has_many :public_body_category_links, :dependent => :destroy
+ has_many :public_body_categories, :order => :category_display_order, :through => :public_body_category_links
+ default_scope order('display_order ASC')
+
+ translates :name
+
+ validates_uniqueness_of :name, :message => N_('Name is already taken')
+ validates_presence_of :name, :message => N_('Name can\'t be blank')
+ validates :display_order, :numericality => { :only_integer => true,
+ :message => N_('Display order must be a number') }
+
+ before_validation :on => :create do
+ unless self.display_order
+ self.display_order = PublicBodyHeading.next_display_order
+ end
+ end
+
+ # Convenience methods for creating/editing translations via forms
+ def find_translation_by_locale(locale)
+ translations.find_by_locale(locale)
+ end
+
+ def translated_versions
+ translations
+ end
+
+ def translated_versions=(translation_attrs)
+ def empty_translation?(attrs)
+ attrs_with_values = attrs.select{ |key, value| value != '' and key != 'locale' }
+ attrs_with_values.empty?
+ end
+
+ if translation_attrs.respond_to? :each_value # Hash => updating
+ translation_attrs.each_value do |attrs|
+ next if empty_translation?(attrs)
+ t = translation_for(attrs[:locale]) || PublicBodyHeading::Translation.new
+ t.attributes = attrs
+ t.save!
+ end
+ else # Array => creating
+ translation_attrs.each do |attrs|
+ next if empty_translation?(attrs)
+ new_translation = PublicBodyHeading::Translation.new(attrs)
+ translations << new_translation
+ end
+ end
+ end
+
+ def add_category(category)
+ unless public_body_categories.include?(category)
+ public_body_categories << category
+ end
+ end
+
+ def self.next_display_order
+ if max = maximum(:display_order)
+ max + 1
+ else
+ 0
+ end
+ end
+
+end