mountain-goat 0.0.1
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.
- data/Gemfile +3 -0
- data/Gemfile.lock +31 -0
- data/History.md +4 -0
- data/LICENSE +20 -0
- data/POST_INSTALL +14 -0
- data/README.md +128 -0
- data/Rakefile +24 -0
- data/init.rb +4 -0
- data/install.rb +53 -0
- data/lib/mountain_goat/controllers/mountain_goat/mountain_goat_controller.rb +6 -0
- data/lib/mountain_goat/controllers/mountain_goat/mountain_goat_converts_controller.rb +107 -0
- data/lib/mountain_goat/controllers/mountain_goat/mountain_goat_metric_variants_controller.rb +80 -0
- data/lib/mountain_goat/controllers/mountain_goat/mountain_goat_metrics_controller.rb +108 -0
- data/lib/mountain_goat/controllers/mountain_goat/mountain_goat_rallies_controller.rb +3 -0
- data/lib/mountain_goat/metric_tracking.rb +241 -0
- data/lib/mountain_goat/models/ci_meta.rb +9 -0
- data/lib/mountain_goat/models/convert.rb +70 -0
- data/lib/mountain_goat/models/convert_meta_type.rb +19 -0
- data/lib/mountain_goat/models/cs_meta.rb +9 -0
- data/lib/mountain_goat/models/metric.rb +10 -0
- data/lib/mountain_goat/models/metric_variant.rb +22 -0
- data/lib/mountain_goat/models/rally.rb +32 -0
- data/lib/mountain_goat/switch_variant.rb +32 -0
- data/lib/mountain_goat/version.rb +3 -0
- data/lib/mountain_goat/views/mountain_goat/layouts/mountain_goat.html.erb +53 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_converts/_convert_form.html.erb +26 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_converts/_convert_meta_type_form.html.erb +27 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_converts/edit.html.erb +13 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_converts/index.html.erb +33 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_converts/new.html.erb +13 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_converts/show.html.erb +59 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metric_variants/_metric_variant_form.html.erb +27 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metric_variants/edit.html.erb +13 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metric_variants/index.html.erb +35 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metric_variants/new.html.erb +15 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metric_variants/show.html.erb +14 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metrics/_metric_form.html.erb +26 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metrics/edit.html.erb +13 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metrics/index.html.erb +29 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metrics/new.html.erb +14 -0
- data/lib/mountain_goat/views/mountain_goat/mountain_goat_metrics/show.html.erb +59 -0
- data/lib/mountain_goat.rb +19 -0
- data/migrations/20090716093747_create_metric_tracking_tables.rb +85 -0
- data/mountain-goat.gemspec +26 -0
- metadata +141 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
class MountainGoatMetricsController < MountainGoatController
|
2
|
+
|
3
|
+
# GET /metrics
|
4
|
+
# GET /metrics.xml
|
5
|
+
def index
|
6
|
+
@metrics = Metric.all
|
7
|
+
|
8
|
+
respond_to do |format|
|
9
|
+
format.html # index.html.erb
|
10
|
+
format.xml { render :xml => @metrics }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /metrics/1
|
15
|
+
# GET /metrics/1.xml
|
16
|
+
def show
|
17
|
+
@metric = Metric.find(params[:id])
|
18
|
+
|
19
|
+
@rates = {}
|
20
|
+
@rates[:served] = []
|
21
|
+
@rates[:conversions] = []
|
22
|
+
@rates[:conversion_rates] = []
|
23
|
+
@rates[:titles] = {}
|
24
|
+
i = 0
|
25
|
+
@metric.metric_variants.each do |mv|
|
26
|
+
@rates[:served].push( { :variant_type => i, :value => mv.served } )
|
27
|
+
@rates[:conversions].push( { :variant_type => i, :value => mv.conversions } )
|
28
|
+
@rates[:conversion_rates].push( { :variant_type => i, :value => mv.conversion_rate } )
|
29
|
+
@rates[:titles].merge!({i => mv.name})
|
30
|
+
i += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
logger.warn @rates[:titles].inspect
|
34
|
+
|
35
|
+
respond_to do |format|
|
36
|
+
format.html # show.html.erb
|
37
|
+
format.xml { render :xml => @metric }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# GET /metrics/new
|
42
|
+
# GET /metrics/new.xml
|
43
|
+
def new
|
44
|
+
@convert = Convert.find(params[:mountain_goat_convert_id])
|
45
|
+
@metric = Metric.new(:convert_id => @convert.id)
|
46
|
+
|
47
|
+
respond_to do |format|
|
48
|
+
format.html # new.html.erb
|
49
|
+
format.xml { render :xml => @metric }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# GET /metrics/1/edit
|
54
|
+
def edit
|
55
|
+
@metric = Metric.find(params[:id])
|
56
|
+
end
|
57
|
+
|
58
|
+
# POST /metrics
|
59
|
+
# POST /metrics.xml
|
60
|
+
def create
|
61
|
+
@metric = Metric.new(params[:metric])
|
62
|
+
|
63
|
+
if @metric.save
|
64
|
+
flash[:notice] = 'Metric was successfully created.'
|
65
|
+
redirect_to mountain_goat_metric_url :id => @metric.id
|
66
|
+
else
|
67
|
+
render :action => "new"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# PUT /metrics/1
|
72
|
+
# PUT /metrics/1.xml
|
73
|
+
def update
|
74
|
+
@metric = Metric.find(params[:id])
|
75
|
+
|
76
|
+
if @metric.update_attributes(params[:metric])
|
77
|
+
flash[:notice] = 'Metric was successfully updated.'
|
78
|
+
redirect_to mountain_goat_metric_url :id => @metric.id
|
79
|
+
else
|
80
|
+
render :action => "edit"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# DELETE /metrics/1
|
85
|
+
# DELETE /metrics/1.xml
|
86
|
+
def destroy
|
87
|
+
@metric = Metric.find(params[:id])
|
88
|
+
@metric.destroy
|
89
|
+
|
90
|
+
respond_to do |format|
|
91
|
+
format.html { redirect_to(mountain_goat_metrics_url) }
|
92
|
+
format.xml { head :ok }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def fresh_metrics
|
97
|
+
#clear metrics
|
98
|
+
#logger.warn "Headerish #{response.headers['cookie']}"
|
99
|
+
cookies.each do |cookie|
|
100
|
+
if cookie[0] =~ /metric_([a-z0-9_]+)/
|
101
|
+
logger.warn "Deleting cookie #{cookie[0]}"
|
102
|
+
cookies.delete cookie[0], :domain => WILD_DOMAIN
|
103
|
+
end
|
104
|
+
end
|
105
|
+
flash[:notice] = "Your metrics have been cleared from cookies."
|
106
|
+
redirect_to :back
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
require File.join([File.dirname(__FILE__), 'switch_variant'])
|
2
|
+
|
3
|
+
module MetricTracking
|
4
|
+
|
5
|
+
#Metric Tracking routes
|
6
|
+
class << ActionController::Routing::Routes;self;end.class_eval do
|
7
|
+
define_method :clear!, lambda {}
|
8
|
+
end
|
9
|
+
|
10
|
+
#TODO: Namespace?
|
11
|
+
ActionController::Routing::Routes.draw do |map|
|
12
|
+
map.mg '/mg', :controller => :mountain_goat_converts, :action => :index
|
13
|
+
map.resources :mountain_goat_metric_variants
|
14
|
+
map.resources :mountain_goat_converts, :has_many => :mountain_goat_metrics
|
15
|
+
map.resources :mountain_goat_metrics, :has_many => :mountain_goat_metric_variants
|
16
|
+
map.resources :mountain_goat_upgrade_orders
|
17
|
+
map.fresh_metrics '/fresh-metrics', :controller => :mountain_goat_metrics, :action => :fresh_metrics
|
18
|
+
end
|
19
|
+
|
20
|
+
module Controller
|
21
|
+
|
22
|
+
######################
|
23
|
+
# Metric Tracking #
|
24
|
+
######################
|
25
|
+
|
26
|
+
def sv(metric_type, convert_type, &block)
|
27
|
+
raise ArgumentError, "Switch variant needs block" if !block_given?
|
28
|
+
metric, convert = get_metric_convert( metric_type, convert_type, true )
|
29
|
+
block.call(SwitchVariant.new( logger, metric, convert, nil ) )
|
30
|
+
|
31
|
+
var = get_switch_metric_variant(metric_type, convert_type)
|
32
|
+
block.call(SwitchVariant.new( logger, metric, convert, var ) )
|
33
|
+
end
|
34
|
+
|
35
|
+
def mv(metric_type, convert_type, default)
|
36
|
+
return get_metric_variant(metric_type, convert_type, default)
|
37
|
+
end
|
38
|
+
|
39
|
+
#shorthand
|
40
|
+
def rc(convert_type, options = {})
|
41
|
+
self.record_conversion(convert_type, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def record_conversion(convert_type, options = {})
|
45
|
+
|
46
|
+
#We want some system for easy default parameter setting
|
47
|
+
if options.include?(:refs) && options[:refs]
|
48
|
+
options = options.merge( :ref_domain => session[:ref_domain], :ref_flyer => session[:ref_flyer], :ref_user => session[:ref_user] )
|
49
|
+
options.delete(:refs)
|
50
|
+
end
|
51
|
+
|
52
|
+
if options.include?(:user) && options[:user]
|
53
|
+
options = options.merge( :user_id => current_user.id ) if signed_in?
|
54
|
+
options.delete(:user)
|
55
|
+
end
|
56
|
+
|
57
|
+
if options.include?(:invitees) && options[:invitees]
|
58
|
+
invitee_meta = {}
|
59
|
+
if session[:invitee_id]
|
60
|
+
invitee = Invitee.find_by_id(session[:invitee_id])
|
61
|
+
if invitee.mailer.clique == @clique
|
62
|
+
options.merge!( { :mailer_id => invitee.mailer.id } )
|
63
|
+
end
|
64
|
+
end
|
65
|
+
options.delete(:invitees)
|
66
|
+
end
|
67
|
+
|
68
|
+
logger.warn "Recording conversion #{convert_type.to_s} with options #{options.inspect}"
|
69
|
+
|
70
|
+
convert = Convert.first( :conditions => { :convert_type => convert_type.to_s } )
|
71
|
+
|
72
|
+
#now, we just create the convert if we don't have one
|
73
|
+
convert = Convert.create!( :convert_type => convert_type.to_s, :name => convert_type.to_s ) if convert.nil?
|
74
|
+
|
75
|
+
#first, let's tally for the conversion itself
|
76
|
+
#we need to see what meta information we should fill based on the conversion type
|
77
|
+
Rally.create!( { :convert_id => convert.id } ).set_meta_data(options)
|
78
|
+
|
79
|
+
#we just converted, let's tally each of our metrics (from cookies)
|
80
|
+
convert.metrics.each do |metric|
|
81
|
+
metric_sym = "metric_#{metric.metric_type}".to_sym
|
82
|
+
metric_variant_sym = "metric_#{metric.metric_type}_variant".to_sym
|
83
|
+
|
84
|
+
value = cookies[metric_sym]
|
85
|
+
variant_id = cookies[metric_variant_sym]
|
86
|
+
|
87
|
+
#logger.warn "Value: #{metric_sym} - #{value}"
|
88
|
+
#logger.warn "Value: #{metric_variant_sym} - #{variant_id}"
|
89
|
+
|
90
|
+
if variant_id.blank? #the user just doesn't have this set
|
91
|
+
next
|
92
|
+
end
|
93
|
+
|
94
|
+
variant = MetricVariant.first(:conditions => { :id => variant_id.to_i } )
|
95
|
+
|
96
|
+
if variant.nil?
|
97
|
+
logger.error "Variant #{variant_id} not in metric variants for #{metric.title}"
|
98
|
+
next
|
99
|
+
end
|
100
|
+
|
101
|
+
if variant.value != value
|
102
|
+
logger.warn "Variant #{variant.name} values differ for metric #{metric.title}. '#{variant.value}' != '#{value}'!"
|
103
|
+
end
|
104
|
+
|
105
|
+
logger.warn "Tallying conversion #{convert.name} for #{metric.title} - #{variant.name} (#{variant.value} - #{variant.id})"
|
106
|
+
variant.tally_convert
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def get_metric_variant(metric_type, convert_type, default)
|
113
|
+
metric_sym = "metric_#{metric_type}".to_sym
|
114
|
+
metric_variant_sym = "metric_#{metric_type}_variant".to_sym
|
115
|
+
|
116
|
+
#first, we'll check for a cookie value
|
117
|
+
if cookies[metric_sym] && !cookies[metric_sym].blank?
|
118
|
+
#we have the cookie
|
119
|
+
|
120
|
+
variant_id = cookies[metric_variant_sym]
|
121
|
+
variant = MetricVariant.first(:conditions => { :id => variant_id.to_i } )
|
122
|
+
if !variant.nil?
|
123
|
+
if variant.metric.tally_each_serve
|
124
|
+
variant.tally_serve
|
125
|
+
end
|
126
|
+
else
|
127
|
+
logger.warn "Serving metric #{metric_type} without finding / tallying variant."
|
128
|
+
end
|
129
|
+
|
130
|
+
return cookies[metric_sym] #it's the best we can do
|
131
|
+
else
|
132
|
+
#we don't have the cookie, let's find a value to set
|
133
|
+
metric, convert = get_metric_convert( metric_type, convert_type, false )
|
134
|
+
|
135
|
+
#to use RAND(), let's not use metrics.metric_variants
|
136
|
+
sum_priority = MetricVariant.first(:select => "SUM(priority) as sum_priority", :conditions => { :metric_id => metric.id } ).sum_priority.to_f
|
137
|
+
|
138
|
+
if sum_priority > 0.0
|
139
|
+
metric_variant = MetricVariant.first(:order => "RAND() * ( priority / #{sum_priority.to_f} ) DESC", :conditions => { :metric_id => metric.id } )
|
140
|
+
end
|
141
|
+
|
142
|
+
if metric_variant.nil?
|
143
|
+
logger.warn "Missing metric variants for #{metric_type}"
|
144
|
+
metric_variant = MetricVariant.create!( :metric_id => metric.id, :value => default, :name => default )
|
145
|
+
end
|
146
|
+
|
147
|
+
metric_variant.tally_serve #donate we served this to a user
|
148
|
+
logger.debug "Serving #{metric_variant.name} (#{metric_variant.value}) for #{metric_sym}"
|
149
|
+
#good, we have a variant, let's store it in session
|
150
|
+
cookies[metric_sym] = { :value => metric_variant.value } #, :domain => WILD_DOMAIN
|
151
|
+
cookies[metric_variant_sym] = { :value => metric_variant.id } #, :domain => WILD_DOMAIN
|
152
|
+
|
153
|
+
return metric_variant.value
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def get_switch_metric_variant(metric_type, convert_type)
|
158
|
+
metric_variant_sym = "metric_#{metric_type}_variant".to_sym
|
159
|
+
|
160
|
+
#first, we'll check for a cookie selection
|
161
|
+
if cookies[metric_variant_sym] && !cookies[metric_variant_sym].blank?
|
162
|
+
#we have the cookie
|
163
|
+
|
164
|
+
variant_id = cookies[metric_variant_sym]
|
165
|
+
variant = MetricVariant.first(:conditions => { :id => variant_id.to_i } )
|
166
|
+
if !variant.nil?
|
167
|
+
|
168
|
+
if variant.metric.tally_each_serve
|
169
|
+
variant.tally_serve
|
170
|
+
end
|
171
|
+
|
172
|
+
return variant
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
#otherwise, it's a big wtf? let's just move on
|
177
|
+
logger.warn "Missing metric variant for #{metric_type} (switch-type), reassigning..."
|
178
|
+
end
|
179
|
+
|
180
|
+
#we don't have the cookie, let's find a value to set
|
181
|
+
metric, convert = get_metric_convert( metric_type, convert_type, true )
|
182
|
+
|
183
|
+
#to use RAND(), let's not use metrics.metric_variants
|
184
|
+
sum_priority = MetricVariant.first(:select => "SUM(priority) as sum_priority", :conditions => { :metric_id => metric.id } ).sum_priority.to_f
|
185
|
+
|
186
|
+
if sum_priority > 0.0
|
187
|
+
metric_variant = MetricVariant.first(:order => "RAND() * ( priority / #{sum_priority.to_f} ) DESC", :conditions => { :metric_id => metric.id } )
|
188
|
+
end
|
189
|
+
|
190
|
+
if metric_variant.nil?
|
191
|
+
logger.warn "Missing metric variants for #{metric_type}"
|
192
|
+
raise ArgumentError, "Missing variants for switch-type #{metric_type}"
|
193
|
+
end
|
194
|
+
|
195
|
+
metric_variant.tally_serve #donate we served this to a user
|
196
|
+
logger.debug "Serving #{metric_variant.name} (#{metric_variant.switch_type}) for #{metric.title} (switch-type)"
|
197
|
+
#good, we have a variant, let's store it in session (not the value, just the selection)
|
198
|
+
cookies[metric_variant_sym] = { :value => metric_variant.id } #, :domain => WILD_DOMAIN
|
199
|
+
|
200
|
+
return metric_variant
|
201
|
+
end
|
202
|
+
|
203
|
+
def get_metric_convert(metric_type, convert_type, is_switch = false)
|
204
|
+
|
205
|
+
metric = Metric.first(:conditions => { :metric_type => metric_type.to_s } )
|
206
|
+
|
207
|
+
conv = Convert.find_by_convert_type( convert_type.to_s )
|
208
|
+
if conv.nil?
|
209
|
+
logger.warn "Missing convert type #{convert_type.to_s} -- creating"
|
210
|
+
conv = Convert.create( :convert_type => convert_type.to_s, :name => convert_type.to_s ) if conv.nil?
|
211
|
+
end
|
212
|
+
|
213
|
+
if metric.nil? #we don't have a metric of this type
|
214
|
+
logger.warn "Missing metric type #{metric_type.to_s} -- creating"
|
215
|
+
metric = Metric.create( :metric_type => metric_type.to_s, :title => metric_type.to_s, :convert_id => conv.id, :is_switch => is_switch )
|
216
|
+
end
|
217
|
+
|
218
|
+
return metric, conv
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
module View
|
223
|
+
def mv(*args, &block)
|
224
|
+
@controller.send(:mv, *args, &block)
|
225
|
+
end
|
226
|
+
|
227
|
+
def sv(*args, &block)
|
228
|
+
@controller.send(:sv, *args, &block)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
class ActionController::Base
|
234
|
+
include MetricTracking::Controller
|
235
|
+
end
|
236
|
+
|
237
|
+
class ActionView::Base
|
238
|
+
include MetricTracking::View
|
239
|
+
end
|
240
|
+
|
241
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class Convert < ActiveRecord::Base
|
2
|
+
|
3
|
+
has_many :metrics
|
4
|
+
has_many :rallies
|
5
|
+
has_many :convert_meta_types
|
6
|
+
has_many :ci_metas, :through => :convert_meta_types
|
7
|
+
has_many :cs_metas, :through => :convert_meta_types
|
8
|
+
|
9
|
+
validates_presence_of :name
|
10
|
+
validates_format_of :convert_type, :with => /[a-z0-9_]{3,50}/i, :message => "must be between 3 and 30 characters, alphanumeric with underscores"
|
11
|
+
validates_uniqueness_of :convert_type
|
12
|
+
|
13
|
+
accepts_nested_attributes_for :convert_meta_types, :reject_if => lambda { |a| a[:name].blank? || a[:var].blank? || a[:meta_type].blank? }, :allow_destroy => true
|
14
|
+
|
15
|
+
def self.by_type(s)
|
16
|
+
Convert.find( :first, :conditions => { :convert_type => s.to_s } )
|
17
|
+
end
|
18
|
+
|
19
|
+
def rallies_for_meta(var)
|
20
|
+
cmt = self.convert_meta_types.find_by_var( var.to_s )
|
21
|
+
return {} if cmt.nil?
|
22
|
+
cmt.meta.map { |m| { m.data => m.rally } }
|
23
|
+
end
|
24
|
+
|
25
|
+
def rallies_for_meta_val(var, data)
|
26
|
+
cmt = self.convert_meta_types.find_by_var( var.to_s )
|
27
|
+
return [] if cmt.nil?
|
28
|
+
cmt.meta.find(:all, :conditions => { :data => data } ).map { |m| m.rally }
|
29
|
+
end
|
30
|
+
|
31
|
+
def rallies_for_meta_val_pivot(var, data, pivot)
|
32
|
+
res = {}
|
33
|
+
cmt = self.convert_meta_types.find_by_var( var.to_s )
|
34
|
+
cmt_pivot = self.convert_meta_types.find_by_var( pivot.to_s )
|
35
|
+
return {} if cmt.nil? || cmt_pivot.nil?
|
36
|
+
cmt.meta.find(:all, :select => "`#{cmt.meta.table_name}`.created_at, cm.data AS pivot", :conditions => { :data => data }, :joins => "LEFT JOIN `#{cmt_pivot.meta.table_name}` cm ON cm.convert_meta_type_id = #{cmt_pivot.id} AND cm.rally_id = `#{cmt.meta.table_name}`.rally_id").each do |c|
|
37
|
+
if !res.include?(c.pivot)
|
38
|
+
res[c.pivot] = []
|
39
|
+
end
|
40
|
+
|
41
|
+
res[c.pivot].push c.created_at
|
42
|
+
end
|
43
|
+
|
44
|
+
res.each { |k,v| v.sort! }
|
45
|
+
res
|
46
|
+
end
|
47
|
+
|
48
|
+
def rallies_for_meta_val_pivot_item(var, data, pivot, item)
|
49
|
+
res = {}
|
50
|
+
cmt = self.convert_meta_types.find_by_var( var.to_s )
|
51
|
+
cmt_pivot = self.convert_meta_types.find_by_var( pivot.to_s )
|
52
|
+
cmt_item = self.convert_meta_types.find_by_var( item.to_s )
|
53
|
+
return {} if cmt.nil? || cmt_pivot.nil? || cmt_item.nil?
|
54
|
+
cmt.meta.find(:all, :select => "`#{cmt.meta.table_name}`.created_at, cm.data AS pivot, ci.data as item", :conditions => { :data => data }, :joins => "LEFT JOIN `#{cmt_pivot.meta.table_name}` cm ON cm.convert_meta_type_id = #{cmt_pivot.id} AND cm.rally_id = `#{cmt.meta.table_name}`.rally_id LEFT JOIN `#{cmt_item.meta.table_name}` ci ON ci.convert_meta_type_id = #{cmt_item.id} AND ci.rally_id = `#{cmt.meta.table_name}`.rally_id").each do |c|
|
55
|
+
if !res.include?(c.pivot)
|
56
|
+
res[c.pivot] = []
|
57
|
+
end
|
58
|
+
|
59
|
+
if cmt_item.meta_type == 'ci_meta'
|
60
|
+
c.item.to_i.times { res[c.pivot].push c.created_at }
|
61
|
+
else
|
62
|
+
res[c.pivot].push c.created_at if c.item == 'yes' #what else?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
res.each { |k,v| v.sort! }
|
67
|
+
res.delete_if { |k,v| v.count == 0 }
|
68
|
+
res
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class ConvertMetaType < ActiveRecord::Base
|
2
|
+
|
3
|
+
belongs_to :convert
|
4
|
+
has_many :ci_metas, :class_name => 'CiMeta', :dependent => :destroy
|
5
|
+
has_many :cs_metas, :class_name => 'CsMeta', :dependent => :destroy
|
6
|
+
|
7
|
+
validates_presence_of :name
|
8
|
+
validates_presence_of :var
|
9
|
+
validates_presence_of :meta_type
|
10
|
+
|
11
|
+
def meta
|
12
|
+
case self.meta_type
|
13
|
+
when 'ci_meta'
|
14
|
+
return self.ci_metas
|
15
|
+
when 'cs_meta'
|
16
|
+
return self.cs_metas
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|