redmine_crm 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/doc/CHANGELOG +4 -0
- data/lib/redmine_crm.rb +28 -20
- data/lib/redmine_crm/{rcrm_acts_as_taggable.rb → acts_as_taggable/rcrm_acts_as_taggable.rb} +93 -87
- data/lib/redmine_crm/acts_as_taggable/tag.rb +81 -0
- data/lib/redmine_crm/acts_as_taggable/tag_list.rb +111 -0
- data/lib/redmine_crm/acts_as_taggable/tagging.rb +16 -0
- data/lib/redmine_crm/acts_as_viewed/rcrm_acts_as_viewed.rb +274 -0
- data/lib/redmine_crm/{rcrm_acts_as_votable.rb → acts_as_votable/rcrm_acts_as_votable.rb} +8 -11
- data/lib/redmine_crm/acts_as_votable/rcrm_acts_as_voter.rb +20 -0
- data/lib/redmine_crm/{votable.rb → acts_as_votable/votable.rb} +36 -47
- data/lib/redmine_crm/{vote.rb → acts_as_votable/vote.rb} +7 -10
- data/lib/redmine_crm/{voter.rb → acts_as_votable/voter.rb} +29 -34
- data/lib/redmine_crm/currency/formatting.rb +0 -3
- data/lib/redmine_crm/currency/heuristics.rb +1 -1
- data/lib/redmine_crm/currency/loader.rb +1 -1
- data/lib/redmine_crm/helpers/tags_helper.rb +1 -3
- data/lib/redmine_crm/helpers/vote_helper.rb +29 -32
- data/lib/redmine_crm/liquid/drops/issues_drop.rb +66 -0
- data/lib/redmine_crm/liquid/drops/news_drop.rb +54 -0
- data/lib/redmine_crm/liquid/drops/projects_drop.rb +86 -0
- data/lib/redmine_crm/liquid/drops/users_drop.rb +72 -0
- data/lib/redmine_crm/liquid/filters/arrays.rb +178 -0
- data/lib/redmine_crm/liquid/filters/base.rb +208 -0
- data/lib/redmine_crm/version.rb +1 -1
- data/redmine_crm.gemspec +1 -1
- data/test/{acts_as_taggable_test.rb → acts_as_taggable/rcrm_acts_as_taggable_test.rb} +114 -151
- data/test/acts_as_taggable/tag_list_test.rb +38 -0
- data/test/acts_as_taggable/tag_test.rb +74 -0
- data/test/acts_as_taggable/tagging_test.rb +15 -0
- data/test/{viewed_test.rb → acts_as_viewed/rcrm_acts_as_viewed_test.rb} +17 -15
- data/test/{votable_test.rb → acts_as_votable/rcrm_acts_as_votable_test.rb} +3 -3
- data/test/acts_as_votable/rcrm_acts_as_voter_test.rb +12 -0
- data/test/{votable_model_test.rb → acts_as_votable/votable_test.rb} +4 -4
- data/test/{voter_model_test.rb → acts_as_votable/voter_test.rb} +7 -7
- data/test/currency_test.rb +10 -10
- data/test/fixtures/issue.rb +6 -2
- data/test/fixtures/issues.yml +13 -1
- data/test/fixtures/news.rb +3 -0
- data/test/fixtures/news.yml +8 -0
- data/test/fixtures/project.rb +8 -0
- data/test/fixtures/projects.yml +10 -0
- data/test/fixtures/user.rb +5 -1
- data/test/fixtures/users.yml +3 -2
- data/test/fixtures/vote_classes.rb +2 -3
- data/test/liquid/drops/issues_drop_test.rb +34 -0
- data/test/liquid/drops/liquid_test.rb +52 -0
- data/test/liquid/drops/news_drop_test.rb +38 -0
- data/test/liquid/drops/projects_drop_test.rb +44 -0
- data/test/liquid/drops/uses_drop_test.rb +36 -0
- data/test/liquid/filters/arrays_filter_test.rb +24 -0
- data/test/liquid/filters/base_filter_test.rb +63 -0
- data/test/liquid/liquid_helper.rb +32 -0
- data/test/money_helper_test.rb +5 -5
- data/test/schema.rb +21 -9
- data/test/test_helper.rb +26 -25
- metadata +76 -28
- data/lib/redmine_crm/rcrm_acts_as_viewed.rb +0 -287
- data/lib/redmine_crm/rcrm_acts_as_voter.rb +0 -27
- data/lib/redmine_crm/tag.rb +0 -81
- data/lib/redmine_crm/tag_list.rb +0 -112
- data/lib/redmine_crm/tagging.rb +0 -20
- data/test/tag_test.rb +0 -64
- data/test/tagging_test.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d6a74714a588b75a1b20bac6fe594b49f7a9a4a
|
4
|
+
data.tar.gz: 62f613b4e7b8a7a038e1a5fe60b4b01ace29f5dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f64b3cbdece3d040b6c7bf05f07e4b97961696988511e501ee55ad68eb9e0b590bf01f5eaa22b5dc4d1b8ad39cf1b1008621e65610a7b5ada5a146b3ef8fd831
|
7
|
+
data.tar.gz: 3747a6d7b4988592833ddf96fbce37981745cdcc1ed58befc9924d18d778d1ab791a749de0d36f0300e8dfef429d4cc49a9e620a807c26d8ced06ba1fa0ae300
|
data/Gemfile
CHANGED
data/doc/CHANGELOG
CHANGED
data/lib/redmine_crm.rb
CHANGED
@@ -1,17 +1,26 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
|
13
|
-
require
|
14
|
-
require
|
1
|
+
require 'redmine_crm/version'
|
2
|
+
|
3
|
+
require 'redmine_crm/acts_as_taggable/tag'
|
4
|
+
require 'redmine_crm/acts_as_taggable/tag_list'
|
5
|
+
require 'redmine_crm/acts_as_taggable/tagging'
|
6
|
+
require 'redmine_crm/acts_as_taggable/rcrm_acts_as_taggable'
|
7
|
+
require 'redmine_crm/acts_as_viewed/rcrm_acts_as_viewed'
|
8
|
+
require 'redmine_crm/acts_as_votable/rcrm_acts_as_votable'
|
9
|
+
require 'redmine_crm/acts_as_votable/rcrm_acts_as_voter'
|
10
|
+
require 'redmine_crm/acts_as_votable/vote'
|
11
|
+
require 'redmine_crm/acts_as_votable/voter'
|
12
|
+
|
13
|
+
require 'redmine_crm/currency'
|
14
|
+
require 'redmine_crm/helpers/tags_helper'
|
15
|
+
require 'redmine_crm/money_helper'
|
16
|
+
|
17
|
+
require 'liquid'
|
18
|
+
require 'redmine_crm/liquid/filters/base'
|
19
|
+
require 'redmine_crm/liquid/filters/arrays'
|
20
|
+
require 'redmine_crm/liquid/drops/issues_drop'
|
21
|
+
require 'redmine_crm/liquid/drops/news_drop'
|
22
|
+
require 'redmine_crm/liquid/drops/projects_drop'
|
23
|
+
require 'redmine_crm/liquid/drops/users_drop'
|
15
24
|
|
16
25
|
if defined?(ActiveRecord::Base)
|
17
26
|
ActiveRecord::Base.extend(RedmineCrm::ActsAsVotable::Votable)
|
@@ -19,9 +28,8 @@ if defined?(ActiveRecord::Base)
|
|
19
28
|
end
|
20
29
|
|
21
30
|
def requires_redmine_crm(arg)
|
22
|
-
|
23
31
|
def compare_versions(requirement, current)
|
24
|
-
raise ArgumentError.new(
|
32
|
+
raise ArgumentError.new('wrong version format') unless check_version_format(requirement)
|
25
33
|
requirement = requirement.split('.').collect(&:to_i)
|
26
34
|
requirement <=> current.slice(0, requirement.size)
|
27
35
|
end
|
@@ -33,11 +41,11 @@ def requires_redmine_crm(arg)
|
|
33
41
|
arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
|
34
42
|
arg.assert_valid_keys(:version, :version_or_higher)
|
35
43
|
|
36
|
-
current = RedmineCrm::VERSION.split(
|
44
|
+
current = RedmineCrm::VERSION.split('.').map { |x| x.to_i }
|
37
45
|
arg.each do |k, req|
|
38
46
|
case k
|
39
47
|
when :version_or_higher
|
40
|
-
raise ArgumentError.new(
|
48
|
+
raise ArgumentError.new(':version_or_higher accepts a version string only') unless req.is_a?(String)
|
41
49
|
unless compare_versions(req, current) <= 0
|
42
50
|
Rails.logger.error "\033[31m[ERROR]\033[0m Redmine requires redmine_crm gem version #{req} or higher (you're using #{RedmineCrm::VERSION}).\n\033[31m[ERROR]\033[0m Please update with 'bundle update redmine_crm'." if Rails.logger
|
43
51
|
abort "\033[31mRedmine requires redmine_crm gem version #{req} or higher (you're using #{RedmineCrm::VERSION}).\nPlease update with 'bundle update redmine_crm'.\033[0m"
|
@@ -53,9 +61,9 @@ def requires_redmine_crm(arg)
|
|
53
61
|
abort "\033[31mRedmine requires redmine_crm gem version between #{req.first} and #{req.last} (you're using #{RedmineCrm::VERSION}).\nPlease update with 'bundle update redmine_crm'.\033[0m"
|
54
62
|
end
|
55
63
|
else
|
56
|
-
raise ArgumentError.new(
|
64
|
+
raise ArgumentError.new(':version option accepts a version string, an array or a range of versions')
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
true
|
61
|
-
end
|
69
|
+
end
|
@@ -1,31 +1,29 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
|
3
|
-
# module ActiveRecord #:nodoc:
|
4
3
|
module RedmineCrm
|
5
|
-
module
|
4
|
+
module ActsAsTaggable #:nodoc:
|
6
5
|
module Taggable #:nodoc:
|
7
6
|
def self.included(base)
|
8
7
|
base.extend(ClassMethods)
|
9
8
|
end
|
10
|
-
|
9
|
+
|
11
10
|
module ClassMethods
|
12
|
-
|
13
11
|
def taggable?
|
14
12
|
false
|
15
13
|
end
|
16
14
|
|
17
15
|
def rcrm_acts_as_taggable
|
18
|
-
has_many :taggings, :as => :taggable, :dependent => :destroy, :class_name => '::RedmineCrm::Tagging'
|
19
|
-
has_many :tags, :through => :taggings, :class_name => '::RedmineCrm::Tag'
|
20
|
-
|
16
|
+
has_many :taggings, :as => :taggable, :dependent => :destroy, :class_name => '::RedmineCrm::ActsAsTaggable::Tagging'
|
17
|
+
has_many :tags, :through => :taggings, :class_name => '::RedmineCrm::ActsAsTaggable::Tag'
|
18
|
+
|
21
19
|
before_save :save_cached_tag_list
|
22
|
-
|
20
|
+
|
23
21
|
after_create :save_tags
|
24
22
|
after_update :save_tags
|
25
|
-
|
26
|
-
include RedmineCrm::
|
27
|
-
extend RedmineCrm::
|
28
|
-
|
23
|
+
|
24
|
+
include RedmineCrm::ActsAsTaggable::Taggable::InstanceMethods
|
25
|
+
extend RedmineCrm::ActsAsTaggable::Taggable::SingletonMethods
|
26
|
+
|
29
27
|
alias_method_chain :reload, :tag_list
|
30
28
|
|
31
29
|
class_eval do
|
@@ -34,11 +32,11 @@ module RedmineCrm
|
|
34
32
|
end
|
35
33
|
end
|
36
34
|
end
|
37
|
-
|
35
|
+
|
38
36
|
def cached_tag_list_column_name
|
39
|
-
|
37
|
+
'cached_tag_list'
|
40
38
|
end
|
41
|
-
|
39
|
+
|
42
40
|
def set_cached_tag_list_column_name(value = nil, &block)
|
43
41
|
define_attr_method :cached_tag_list_column_name, value, &block
|
44
42
|
end
|
@@ -47,9 +45,9 @@ module RedmineCrm
|
|
47
45
|
# === Options hash:
|
48
46
|
# * <tt>:table_name</tt> - use a table name other than viewings
|
49
47
|
# To be used during migration, but can also be used in other places
|
50
|
-
def create_taggable_table
|
51
|
-
tag_name_table
|
52
|
-
|
48
|
+
def create_taggable_table(options = {})
|
49
|
+
tag_name_table = options[:tags] || :tags
|
50
|
+
|
53
51
|
if !self.connection.table_exists?(tag_name_table)
|
54
52
|
self.connection.create_table(tag_name_table) do |t|
|
55
53
|
t.column :name, :string
|
@@ -61,89 +59,88 @@ module RedmineCrm
|
|
61
59
|
self.connection.create_table(taggings_name_table) do |t|
|
62
60
|
t.column :tag_id, :integer
|
63
61
|
t.column :taggable_id, :integer
|
64
|
-
|
62
|
+
|
65
63
|
# You should make sure that the column created is
|
66
64
|
# long enough to store the required class names.
|
67
65
|
t.column :taggable_type, :string
|
68
|
-
|
66
|
+
|
69
67
|
t.column :created_at, :datetime
|
70
68
|
end
|
71
69
|
|
72
70
|
self.connection.add_index :taggings, :tag_id
|
73
71
|
self.connection.add_index :taggings, [:taggable_id, :taggable_type]
|
74
72
|
end
|
75
|
-
|
76
73
|
end
|
77
|
-
|
78
|
-
def drop_taggable_table
|
79
|
-
tag_name_table
|
74
|
+
|
75
|
+
def drop_taggable_table(options = {})
|
76
|
+
tag_name_table = options[:tags] || :tags
|
80
77
|
if self.connection.table_exists?(tag_name_table)
|
81
78
|
self.connection.drop_table tag_name_table
|
82
79
|
end
|
80
|
+
|
83
81
|
taggings_name_table = options[:taggings] || :taggings
|
84
82
|
if self.connection.table_exists?(taggings_name_table)
|
85
83
|
self.connection.drop_table taggings_name_table
|
86
84
|
end
|
87
|
-
|
88
85
|
end
|
89
86
|
end
|
90
|
-
|
87
|
+
|
91
88
|
module SingletonMethods
|
92
|
-
#Return all avalible tags for a project or global
|
93
|
-
#Example: Question.available_tags(@project_id )
|
94
|
-
def available_tags(project=nil, limit=30)
|
89
|
+
# Return all avalible tags for a project or global
|
90
|
+
# Example: Question.available_tags(@project_id )
|
91
|
+
def available_tags(project = nil, limit = 30)
|
95
92
|
scope = Tag.where({})
|
96
|
-
class_name = quote_value(base_class.name
|
93
|
+
class_name = quote_value(base_class.name)
|
97
94
|
join = []
|
98
95
|
join << "JOIN #{Tagging.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id "
|
99
|
-
join << "JOIN #{table_name} ON #{table_name}.id = #{Tagging.table_name}.taggable_id
|
96
|
+
join << "JOIN #{table_name} ON #{table_name}.id = #{Tagging.table_name}.taggable_id
|
100
97
|
AND #{Tagging.table_name}.taggable_type = #{class_name} "
|
101
|
-
if self.attribute_names.include?
|
98
|
+
if self.attribute_names.include?('project_id')
|
102
99
|
if project
|
103
|
-
|
100
|
+
join << "JOIN #{Project.table_name} ON #{Project.table_name}.id = #{table_name}.project_id"
|
104
101
|
else
|
105
|
-
|
102
|
+
scope = scope.where("#{table_name}.project_id IS NULL")
|
106
103
|
end
|
107
104
|
end
|
108
105
|
|
109
|
-
group_fields =
|
106
|
+
group_fields = ''
|
110
107
|
group_fields << ", #{Tag.table_name}.created_at" if Tag.respond_to?(:created_at)
|
111
108
|
group_fields << ", #{Tag.table_name}.updated_at" if Tag.respond_to?(:updated_at)
|
112
109
|
|
113
110
|
scope = scope.joins(join.join(' '))
|
114
111
|
scope = scope.select("#{Tag.table_name}.*, COUNT(DISTINCT #{Tagging.table_name}.taggable_id) AS count")
|
115
|
-
scope = scope.group("#{Tag.table_name}.id, #{Tag.table_name}.name #{group_fields}
|
112
|
+
scope = scope.group("#{Tag.table_name}.id, #{Tag.table_name}.name #{group_fields}")
|
113
|
+
scope = scope.having('COUNT(*) > 0')
|
116
114
|
scope = scope.order("#{Tag.table_name}.name")
|
117
115
|
scope = scope.limit(limit) if limit
|
118
116
|
scope
|
119
117
|
end
|
120
118
|
# Returns an array of related tags.
|
121
119
|
# Related tags are all the other tags that are found on the models tagged with the provided tags.
|
122
|
-
#
|
120
|
+
#
|
123
121
|
# Pass either a tag, string, or an array of strings or tags.
|
124
|
-
#
|
122
|
+
#
|
125
123
|
# Options:
|
126
124
|
# :order - SQL Order how to order the tags. Defaults to "count DESC, tags.name".
|
127
125
|
def find_related_tags(tags, options = {})
|
128
126
|
tags = tags.is_a?(Array) ? TagList.new(tags.map(&:to_s)) : TagList.from(tags)
|
129
|
-
|
127
|
+
|
130
128
|
related_models = find_tagged_with(tags)
|
131
|
-
|
129
|
+
|
132
130
|
return [] if related_models.blank?
|
133
|
-
|
131
|
+
|
134
132
|
related_ids = related_models.map{|c| c.id }.join(",")
|
135
|
-
Tag.select(
|
133
|
+
Tag.select(
|
136
134
|
"#{Tag.table_name}.*, COUNT(#{Tag.table_name}.id) AS count").joins(
|
137
135
|
"JOIN #{Tagging.table_name} ON #{Tagging.table_name}.taggable_type = '#{base_class.name}'
|
138
136
|
AND #{Tagging.table_name}.taggable_id IN (#{related_ids})
|
139
137
|
AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id").order(
|
140
138
|
options[:order] || "count DESC, #{Tag.table_name}.name").group(
|
141
|
-
"#{Tag.table_name}.id, #{Tag.table_name}.name HAVING #{Tag.table_name}.name NOT IN (#{tags.map { |n| quote_value(n
|
142
|
-
# }))
|
139
|
+
"#{Tag.table_name}.id, #{Tag.table_name}.name HAVING #{Tag.table_name}.name NOT IN (#{tags.map { |n| quote_value(n) }.join(",")})")
|
143
140
|
end
|
144
|
-
|
141
|
+
|
145
142
|
# Pass either a tag, string, or an array of strings or tags.
|
146
|
-
#
|
143
|
+
#
|
147
144
|
# Options:
|
148
145
|
# :exclude - Find models that are not tagged with the given tags
|
149
146
|
# :match_all - Find models that match all of the given tags, not just one
|
@@ -151,32 +148,32 @@ module RedmineCrm
|
|
151
148
|
def find_tagged_with(*args)
|
152
149
|
options = find_options_for_find_tagged_with(*args)
|
153
150
|
options.blank? ? [] : select(options[:select]).where(options[:conditions]).joins(options[:joins]).order(options[:order]).to_a
|
154
|
-
# find(:all, options)
|
155
151
|
end
|
152
|
+
|
156
153
|
alias_method :tagged_with, :find_tagged_with
|
157
|
-
|
154
|
+
|
158
155
|
def find_options_for_find_tagged_with(tags, options = {})
|
159
156
|
tags = tags.is_a?(Array) ? TagList.new(tags.map(&:to_s)) : TagList.from(tags)
|
160
157
|
options = options.dup
|
161
|
-
|
158
|
+
|
162
159
|
return {} if tags.empty?
|
163
|
-
|
160
|
+
|
164
161
|
conditions = []
|
165
162
|
conditions << sanitize_sql(options.delete(:conditions)) if options[:conditions]
|
166
|
-
|
163
|
+
|
167
164
|
taggings_alias, tags_alias = "#{table_name}_taggings", "#{table_name}_tags"
|
168
|
-
|
165
|
+
|
169
166
|
joins = [
|
170
|
-
"INNER JOIN #{Tagging.table_name} #{taggings_alias} ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key} AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name
|
167
|
+
"INNER JOIN #{Tagging.table_name} #{taggings_alias} ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key} AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}",
|
171
168
|
"INNER JOIN #{Tag.table_name} #{tags_alias} ON #{tags_alias}.id = #{taggings_alias}.tag_id"
|
172
169
|
]
|
173
|
-
|
170
|
+
|
174
171
|
if options.delete(:exclude)
|
175
172
|
conditions << <<-END
|
176
173
|
#{table_name}.id NOT IN
|
177
174
|
(SELECT #{Tagging.table_name}.taggable_id FROM #{Tagging.table_name}
|
178
175
|
INNER JOIN #{Tag.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id
|
179
|
-
WHERE #{tags_condition(tags)} AND #{Tagging.table_name}.taggable_type = #{quote_value(base_class.name
|
176
|
+
WHERE #{tags_condition(tags)} AND #{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})
|
180
177
|
END
|
181
178
|
else
|
182
179
|
if options.delete(:match_all)
|
@@ -185,23 +182,23 @@ module RedmineCrm
|
|
185
182
|
conditions << tags_condition(tags, tags_alias)
|
186
183
|
end
|
187
184
|
end
|
188
|
-
|
185
|
+
|
189
186
|
{ :select => "DISTINCT #{table_name}.* ",
|
190
187
|
:joins => joins.join(" "),
|
191
188
|
:conditions => conditions.join(" AND ")
|
192
189
|
}.reverse_merge!(options)
|
193
190
|
end
|
194
|
-
|
191
|
+
|
195
192
|
def joins_for_match_all_tags(tags)
|
196
193
|
joins = []
|
197
|
-
|
194
|
+
|
198
195
|
tags.each_with_index do |tag, index|
|
199
196
|
taggings_alias, tags_alias = "taggings_#{index}", "tags_#{index}"
|
200
197
|
|
201
198
|
join = <<-END
|
202
199
|
INNER JOIN #{Tagging.table_name} #{taggings_alias} ON
|
203
200
|
#{taggings_alias}.taggable_id = #{table_name}.#{primary_key} AND
|
204
|
-
#{taggings_alias}.taggable_type = #{quote_value(base_class.name
|
201
|
+
#{taggings_alias}.taggable_type = #{quote_value(base_class.name)}
|
205
202
|
|
206
203
|
INNER JOIN #{Tag.table_name} #{tags_alias} ON
|
207
204
|
#{taggings_alias}.tag_id = #{tags_alias}.id AND
|
@@ -210,12 +207,12 @@ module RedmineCrm
|
|
210
207
|
|
211
208
|
joins << sanitize_sql([join, tag])
|
212
209
|
end
|
213
|
-
|
214
|
-
joins.join(
|
210
|
+
|
211
|
+
joins.join(' ')
|
215
212
|
end
|
216
|
-
|
213
|
+
|
217
214
|
# Calculate the tag counts for all tags.
|
218
|
-
#
|
215
|
+
#
|
219
216
|
# See Tag.counts for available options.
|
220
217
|
def tag_counts(options = {})
|
221
218
|
# Tag.find(:all, find_options_for_tag_counts(options))
|
@@ -223,35 +220,39 @@ module RedmineCrm
|
|
223
220
|
Tag.select(opt[:select]).where(opt[:conditions]).joins(opt[:joins]).group(opt[:group]).having(opt[:having]).order(opt[:order]).limit(options[:limit])
|
224
221
|
end
|
225
222
|
alias_method :all_tag_counts, :tag_counts
|
226
|
-
|
223
|
+
|
227
224
|
def find_options_for_tag_counts(options = {})
|
228
225
|
options = options.dup
|
229
226
|
scope = scope_attributes
|
230
227
|
# scope(:find)
|
231
|
-
|
228
|
+
|
232
229
|
conditions = []
|
233
230
|
conditions << send(:sanitize_conditions, options.delete(:conditions)) if options[:conditions]
|
234
|
-
conditions << send(:sanitize_conditions, scope) if scope
|
235
|
-
conditions << "#{Tagging.table_name}.taggable_type = #{quote_value(base_class.name
|
236
|
-
conditions << type_condition unless descends_from_active_record?
|
231
|
+
conditions << send(:sanitize_conditions, scope) if scope
|
232
|
+
conditions << "#{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}"
|
233
|
+
conditions << type_condition unless descends_from_active_record?
|
237
234
|
conditions.compact!
|
238
235
|
conditions = conditions.join(" AND ")
|
239
|
-
|
236
|
+
|
240
237
|
joins = ["INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"]
|
241
238
|
joins << options.delete(:joins) if options[:joins].present?
|
242
239
|
# joins << scope[:joins] if scope && scope[:joins].present?
|
243
240
|
joins = joins.join(" ")
|
244
|
-
|
241
|
+
|
245
242
|
options = { :conditions => conditions, :joins => joins }.update(options)
|
246
|
-
|
243
|
+
|
247
244
|
Tag.options_for_counts(options)
|
248
245
|
end
|
249
246
|
|
250
247
|
def caching_tag_list?
|
251
248
|
column_names.include?(cached_tag_list_column_name)
|
252
249
|
end
|
253
|
-
|
250
|
+
|
254
251
|
private
|
252
|
+
def quote_value(object)
|
253
|
+
sanitize(object)
|
254
|
+
end
|
255
|
+
|
255
256
|
def tags_condition(tags, table_name = Tag.table_name)
|
256
257
|
condition = tags.map { |t| sanitize_sql(["#{table_name}.name LIKE ?", t]) }.join(" OR ")
|
257
258
|
"(" + condition + ")" unless condition.blank?
|
@@ -270,39 +271,39 @@ module RedmineCrm
|
|
270
271
|
"(#{segments.join(') AND (')})" unless segments.empty?
|
271
272
|
end
|
272
273
|
end
|
273
|
-
|
274
|
+
|
274
275
|
module InstanceMethods
|
275
276
|
def tag_list
|
276
|
-
return @tag_list if @tag_list
|
277
|
-
|
278
|
-
if self.class.caching_tag_list?
|
277
|
+
return @tag_list if @tag_list ||= nil
|
278
|
+
|
279
|
+
if self.class.caching_tag_list? && !(cached_value = send(self.class.cached_tag_list_column_name)).nil?
|
279
280
|
@tag_list = TagList.from(cached_value)
|
280
281
|
else
|
281
282
|
@tag_list = TagList.new(*tags.map(&:name))
|
282
283
|
end
|
283
284
|
end
|
284
|
-
|
285
|
+
|
285
286
|
def tag_list=(value)
|
286
287
|
@tag_list = TagList.from(value)
|
287
288
|
end
|
288
|
-
|
289
|
+
|
289
290
|
def save_cached_tag_list
|
290
291
|
if self.class.caching_tag_list?
|
291
292
|
self[self.class.cached_tag_list_column_name] = tag_list.to_s
|
292
293
|
end
|
293
294
|
end
|
294
|
-
|
295
|
+
|
295
296
|
#build list from related tags
|
296
297
|
def all_tags_list
|
297
298
|
tags.pluck(:name)
|
298
299
|
end
|
299
|
-
|
300
|
+
|
300
301
|
def save_tags
|
301
302
|
return unless @tag_list
|
302
|
-
|
303
|
+
|
303
304
|
new_tag_names = @tag_list - tags.map(&:name)
|
304
305
|
old_tags = tags.reject { |tag| @tag_list.include?(tag.name) }
|
305
|
-
|
306
|
+
|
306
307
|
self.class.transaction do
|
307
308
|
if old_tags.any?
|
308
309
|
taggings.where("tag_id IN (?)", old_tags.map(&:id)).each(&:destroy)
|
@@ -312,20 +313,20 @@ module RedmineCrm
|
|
312
313
|
tags << Tag.find_or_create_with_like_by_name(new_tag_name)
|
313
314
|
end
|
314
315
|
end
|
315
|
-
|
316
|
+
|
316
317
|
true
|
317
318
|
end
|
318
|
-
|
319
|
+
|
319
320
|
# Calculate the tag counts for the tags used by this model.
|
320
321
|
#
|
321
322
|
# The possible options are the same as the tag_counts class method.
|
322
323
|
def tag_counts(options = {})
|
323
324
|
return [] if tag_list.blank?
|
324
|
-
|
325
|
+
|
325
326
|
options[:conditions] = self.class.send(:merge_conditions, options[:conditions], self.class.send(:tags_condition, tag_list))
|
326
327
|
self.class.tag_counts(options)
|
327
328
|
end
|
328
|
-
|
329
|
+
|
329
330
|
def reload_with_tag_list(*args) #:nodoc:
|
330
331
|
@tag_list = nil
|
331
332
|
reload_without_tag_list(*args)
|
@@ -335,4 +336,9 @@ module RedmineCrm
|
|
335
336
|
end
|
336
337
|
end
|
337
338
|
|
338
|
-
ActiveRecord::Base.send(:include, RedmineCrm::
|
339
|
+
ActiveRecord::Base.send(:include, RedmineCrm::ActsAsTaggable::Taggable)
|
340
|
+
|
341
|
+
# Class aliases
|
342
|
+
RedmineCrm::Tag = RedmineCrm::ActsAsTaggable::Tag
|
343
|
+
RedmineCrm::TagList = RedmineCrm::ActsAsTaggable::TagList
|
344
|
+
RedmineCrm::Tagging = RedmineCrm::ActsAsTaggable::Tagging
|