tagtical 1.5.4 → 1.5.5

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.4
1
+ 1.5.5
data/lib/tagtical/tag.rb CHANGED
@@ -51,16 +51,24 @@ module Tagtical
51
51
  # Method used to ensure list of tags for the given Tag class.
52
52
  # Returns a hash with the key being the value from the tag list and the value being the saved tag.
53
53
  def find_or_create_tags(*tag_list)
54
+ find_or_build_or_create_tags(:create!, *tag_list)
55
+ end
56
+
57
+ def find_or_build_tags(*tag_list)
58
+ find_or_build_or_create_tags(:new, *tag_list)
59
+ end
60
+
61
+ def find_or_build_or_create_tags(operation, *tag_list)
54
62
  tag_list = [tag_list].flatten
55
63
  return {} if tag_list.empty?
56
64
 
57
65
  existing_tags = where_any_like(tag_list).all
58
66
  tag_list.each_with_object({}) do |value, tag_lookup|
59
- tag_lookup[detect_comparable(existing_tags, value) || create!(:value => value)] = value
67
+ tag_lookup[detect_comparable(existing_tags, value) || send(operation, :value => value)] = value
60
68
  end
61
69
  end
62
70
 
63
- # Save disc space by not having to put in "Tagtical::Tag" repeatedly
71
+ # Save disc space by not having to put in "Tagtical::Tag" repeatedly
64
72
  def sti_name
65
73
  Tagtical::Tag==self ? nil : super
66
74
  end
@@ -335,8 +335,23 @@ module Tagtical::Taggable
335
335
  true
336
336
  end
337
337
 
338
+
338
339
  private
339
340
 
341
+ def must_have_valid_tags
342
+ tags = []
343
+ tag_types.each do |tag_type|
344
+ tag_lists = tag_list_cache_on(tag_type) || {}
345
+ tag_lists.each do |expanded_tag_types, tag_list|
346
+ next unless expanded_tag_types.include?(tag_type)
347
+ tags += tag_type.klass.find_or_build_tags(tag_list.uniq).keys
348
+ end
349
+ end
350
+ tags.each do |tag|
351
+ tag.errors.to_a.each { |error| self.errors.add(:tags, error) } unless tag.valid?
352
+ end
353
+ end
354
+
340
355
  def remove_tag_caches_on(tag_types)
341
356
  Array(tag_types).each do |tag_type|
342
357
  [:all_tag_list_ivar, :tag_list_ivar, :scope_ivar].each do |ivar_method|
@@ -32,6 +32,7 @@ module Tagtical
32
32
 
33
33
  has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "Tagtical::Tagging"
34
34
  has_many :tags, :through => :taggings, :class_name => "Tagtical::Tag"
35
+ validate :must_have_valid_tags
35
36
 
36
37
  class_eval do
37
38
  def self.taggable?
@@ -49,4 +50,4 @@ module Tagtical
49
50
 
50
51
  end
51
52
  end
52
- end
53
+ end
@@ -76,6 +76,29 @@ describe Tagtical do
76
76
  end
77
77
  end
78
78
 
79
+ describe "Validating" do
80
+ when_possible_values_specified(:klass => Tag::Skill) do
81
+
82
+ before do
83
+ @taggable = TaggableModel.new(:name => "taggable")
84
+ end
85
+
86
+ it "should not be valid if the tag is not valid and self is a new record" do
87
+ @taggable.skill_list = "knife, foo"
88
+ @taggable.should_not be_valid
89
+ @taggable.errors[:tags].should be_present
90
+ end
91
+
92
+ it "should not be valid if the tag is not valid and self is not a new record" do
93
+ @taggable.save!
94
+ @taggable.set_tag_list_on("skill", "knife, foo")
95
+ @taggable.should_not be_valid
96
+ @taggable.errors[:tags].should be_present
97
+ end
98
+
99
+ end
100
+ end
101
+
79
102
  describe "Reloading" do
80
103
  it "should save a model instantiated by Model.find" do
81
104
  taggable = TaggableModel.create!(:name => "Taggable")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tagtical
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.5.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-22 00:00:00.000000000 -08:00
12
+ date: 2012-01-14 00:00:00.000000000 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &2156267300 !ruby/object:Gem::Requirement
17
+ requirement: &2166180240 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - <=
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 3.0.5
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2156267300
25
+ version_requirements: *2166180240
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec
28
- requirement: &2156266820 !ruby/object:Gem::Requirement
28
+ requirement: &2166179760 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2156266820
36
+ version_requirements: *2166179760
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: sqlite3-ruby
39
- requirement: &2156266340 !ruby/object:Gem::Requirement
39
+ requirement: &2166179280 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *2156266340
47
+ version_requirements: *2166179280
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: mysql
50
- requirement: &2156265860 !ruby/object:Gem::Requirement
50
+ requirement: &2166178800 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *2156265860
58
+ version_requirements: *2166178800
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: jeweler
61
- requirement: &2156265380 !ruby/object:Gem::Requirement
61
+ requirement: &2166178320 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *2156265380
69
+ version_requirements: *2166178320
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rcov
72
- requirement: &2156264900 !ruby/object:Gem::Requirement
72
+ requirement: &2166194980 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: '0'
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *2156264900
80
+ version_requirements: *2166194980
81
81
  description: Tagtical allows you do create subclasses for Tag and add additional functionality
82
82
  in an STI fashion. For example. You could do Tag::Color.find_by_name('blue').to_rgb.
83
83
  It also supports storing weights or relevance on the taggings.