diff --git a/app/models/tag.rb b/app/models/tag.rb
index b9f3ffdb8..eb13f5b64 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -1,6 +1,7 @@
class Tag < ActiveRecord::Base
METATAGS = "-user|user|-approver|approver|commenter|comm|noter|-pool|pool|-fav|fav|sub|md5|-rating|rating|-locked|locked|width|height|mpixels|score|favcount|filesize|source|-source|id|-id|date|age|order|-status|status|tagcount|gentags|arttags|chartags|copytags|parent|-parent|pixiv_id|pixiv"
- attr_accessible :category
+ attr_accessible :category, :as => [:moderator, :janitor, :contributor, :gold, :member, :anonymous, :default, :builder, :admin]
+ attr_accessible :is_locked, :as => [:moderator, :janitor, :admin]
has_one :wiki_page, :foreign_key => "name", :primary_key => "title"
module ApiMethods
@@ -141,7 +142,7 @@ class Tag < ActiveRecord::Base
if category
category_id = categories.value_for(category)
- if category_id != tag.category && (CurrentUser.is_builder? || tag.post_count <= 50)
+ if category_id != tag.category && !tag.is_locked? && (CurrentUser.is_builder? || tag.post_count <= 50)
tag.update_column(:category, category_id)
tag.update_category_cache_for_all
end
diff --git a/app/views/tags/edit.html.erb b/app/views/tags/edit.html.erb
index f08fdf5a7..6ae686874 100644
--- a/app/views/tags/edit.html.erb
+++ b/app/views/tags/edit.html.erb
@@ -3,7 +3,14 @@
Tag: <%= @tag.name %>
<%= simple_form_for(@tag) do |f| %>
- <%= f.input :category, :collection => Danbooru.config.canonical_tag_category_mapping.to_a, :include_blank => false %>
+ <% unless @tag.is_locked? %>
+ <%= f.input :category, :collection => Danbooru.config.canonical_tag_category_mapping.to_a, :include_blank => false %>
+ <% end %>
+
+ <% if CurrentUser.user.is_janitor? %>
+ <%= f.input :is_locked, :collection => [["No", "false"], ["Yes", "true"]] %>
+ <% end %>
+
<%= f.button :submit, "Submit" %>
<% end %>
diff --git a/db/migrate/20130620215658_add_is_locked_to_tags.rb b/db/migrate/20130620215658_add_is_locked_to_tags.rb
new file mode 100644
index 000000000..1d9575a15
--- /dev/null
+++ b/db/migrate/20130620215658_add_is_locked_to_tags.rb
@@ -0,0 +1,6 @@
+class AddIsLockedToTags < ActiveRecord::Migration
+ def change
+ execute "set statement_timeout = 0"
+ add_column :tags, :is_locked, :boolean, :null => false, :default => false
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 1bdcbd170..c6d301fe2 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -2488,7 +2488,8 @@ CREATE TABLE tags (
related_tags text,
related_tags_updated_at timestamp without time zone,
created_at timestamp without time zone NOT NULL,
- updated_at timestamp without time zone NOT NULL
+ updated_at timestamp without time zone NOT NULL,
+ is_locked boolean DEFAULT false NOT NULL
);
@@ -6421,4 +6422,6 @@ INSERT INTO schema_migrations (version) VALUES ('20130506154136');
INSERT INTO schema_migrations (version) VALUES ('20130606224559');
-INSERT INTO schema_migrations (version) VALUES ('20130618230158');
\ No newline at end of file
+INSERT INTO schema_migrations (version) VALUES ('20130618230158');
+
+INSERT INTO schema_migrations (version) VALUES ('20130620215658');
\ No newline at end of file
diff --git a/test/unit/tag_test.rb b/test/unit/tag_test.rb
index 63b7b775d..d6e9add27 100644
--- a/test/unit/tag_test.rb
+++ b/test/unit/tag_test.rb
@@ -84,6 +84,22 @@ class TagTest < ActiveSupport::TestCase
MEMCACHE.flush_all
end
+ should "be lockable by a janitor" do
+ @tag = FactoryGirl.create(:tag)
+ @tag.update_attributes({:is_locked => true}, :as => :janitor)
+ @tag.reload
+ assert_equal(true, @tag.is_locked?)
+ end
+
+ should "not be lockable by a user" do
+ @tag = FactoryGirl.create(:tag)
+ assert_raises(ActiveModel::MassAssignmentSecurity::Error) do
+ @tag.update_attributes({:is_locked => true}, :as => :member)
+ end
+ @tag.reload
+ assert_equal(false, @tag.is_locked?)
+ end
+
should "know its category name" do
@tag = FactoryGirl.create(:artist_tag)
assert_equal("Artist", @tag.category_name)
@@ -153,6 +169,14 @@ class TagTest < ActiveSupport::TestCase
end
end
+ should "not change the category is the tag is locked" do
+ tag = FactoryGirl.create(:tag, :is_locked => true)
+ assert_equal(true, tag.is_locked?)
+ Tag.find_or_create_by_name("artist:#{tag.name}")
+ tag.reload
+ assert_equal(0, tag.category)
+ end
+
should "be created when one doesn't exist" do
assert_difference("Tag.count", 1) do
tag = Tag.find_or_create_by_name("hoge")