experimental 0.4.0 → 0.5.0
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/README.markdown +8 -151
- data/Rakefile +1 -19
- data/lib/experimental.rb +4 -2
- data/{app/models → lib}/experimental/experiment.rb +14 -11
- data/lib/experimental/loader.rb +1 -1
- data/lib/experimental/population.rb +7 -0
- data/{app/models → lib}/experimental/population/default.rb +0 -0
- data/{app/models → lib}/experimental/population/filter.rb +0 -0
- data/{app/models → lib}/experimental/population/new_users.rb +0 -0
- data/{app/models → lib}/experimental/subject.rb +0 -0
- data/lib/experimental/version.rb +1 -1
- metadata +8 -14
- data/app/views/experimental/_experiment.html.erb +0 -16
- data/app/views/experimental/_index.html.erb +0 -50
- data/app/views/experimental/_links.html.erb +0 -7
- data/app/views/experimental/_new.html.erb +0 -37
- data/lib/experimental/controller_actions.rb +0 -90
- data/lib/experimental/middleware.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c3ca7d05e6f83ec23e057defc0da8e4d8b94b6f
|
4
|
+
data.tar.gz: 19dd91453b0154b0d8cbc4b7c03e02860ba796e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f460e8ef869e751e103a936cf99c921293e700dd15387391ce4b84ed9207ecf49c472df59a02e29d38b471afa77ce708ff07d20722165585665e6a4d3dd6b79
|
7
|
+
data.tar.gz: 24eeb5bec5c23fcbb3354804368d21fbad288b278942c82b191ead834b2e61b59bf5116443d8e03d5416a86021c2a38dcad013a6a7b2ab45b8fcc81c71b8833a
|
data/README.markdown
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# Experimental
|
1
|
+
# Experimental [](https://travis-ci.org/howaboutwe/experimental)
|
2
|
+
|
2
3
|
Experimental is an Split testing framework for Rails.
|
3
4
|
It was written with a few goals in mind:
|
4
5
|
* Split the users in a non-predictable pattern (i.e. half of the users won't always
|
@@ -14,136 +15,6 @@ be removed make the site explode
|
|
14
15
|
|
15
16
|
`rails g experimental`
|
16
17
|
|
17
|
-
### Routes
|
18
|
-
|
19
|
-
```ruby
|
20
|
-
resources :experiments, only: [:index, :new, :create] do
|
21
|
-
collection do
|
22
|
-
get :inactive
|
23
|
-
post :set_winner
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
namespace :singles_admin do
|
28
|
-
resources :experiments, only: [:index, :new, :create] do
|
29
|
-
collection do
|
30
|
-
get :inactive
|
31
|
-
post :set_winner
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
```
|
37
|
-
|
38
|
-
### Admin Frontend
|
39
|
-
|
40
|
-
#### Create your own admin controller:
|
41
|
-
```ruby
|
42
|
-
class Admin::ExperimentsController < ApplicationController
|
43
|
-
include Experimental::ControllerActions
|
44
|
-
|
45
|
-
alias_method :index, :experiments_index
|
46
|
-
alias_method :new, :experiments_new
|
47
|
-
alias_method :set_winner, :experiments_set_winner
|
48
|
-
|
49
|
-
def create
|
50
|
-
if experiments_create
|
51
|
-
redirect_to admin_experiments_path
|
52
|
-
else
|
53
|
-
render :new
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def base_resource_name
|
58
|
-
"singles_admin_experiment"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
```
|
62
|
-
|
63
|
-
#### Using ActiveAdmin:
|
64
|
-
|
65
|
-
`rails g active_admin:resource Experiment`
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
require 'experimental/controller_actions'
|
69
|
-
|
70
|
-
ActiveAdmin.register Experimental::Experiment, as: "Experiment" do
|
71
|
-
actions :index, :new, :create
|
72
|
-
filter :name
|
73
|
-
|
74
|
-
controller do
|
75
|
-
class_eval do
|
76
|
-
include Experimental::ControllerActions
|
77
|
-
end
|
78
|
-
|
79
|
-
def base_resource_name
|
80
|
-
"admin_experiment"
|
81
|
-
end
|
82
|
-
|
83
|
-
def create
|
84
|
-
if experiments_create
|
85
|
-
redirect_to admin_experiments_path
|
86
|
-
else
|
87
|
-
render :new
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def new
|
92
|
-
experiments_new
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# collection_actions force active_admin to create a route
|
97
|
-
collection_action :set_winner, method: :post do
|
98
|
-
experiments_set_winner
|
99
|
-
end
|
100
|
-
|
101
|
-
# can do this instead of the ended_or_removed scope below
|
102
|
-
# you will need to add a link to inactive_admins_experiments_path
|
103
|
-
# in your view
|
104
|
-
collection_action :inactive do
|
105
|
-
experiments_inactive
|
106
|
-
render template: 'admin/experiments/index'
|
107
|
-
end
|
108
|
-
|
109
|
-
scope :in_progress, :default => true do |experiments|
|
110
|
-
experiments.in_progress
|
111
|
-
end
|
112
|
-
|
113
|
-
scope :ended_or_removed do |experiments|
|
114
|
-
@include_inactive = true
|
115
|
-
experiments.ended_or_removed
|
116
|
-
end
|
117
|
-
|
118
|
-
index do
|
119
|
-
render template: 'admin/experiments/index'
|
120
|
-
end
|
121
|
-
|
122
|
-
form partial: 'new'
|
123
|
-
end
|
124
|
-
```
|
125
|
-
|
126
|
-
#### Views
|
127
|
-
|
128
|
-
create an index and new view in appropriate view folder, i.e.
|
129
|
-
|
130
|
-
`app/views/admin/experiments/index.html.erb`
|
131
|
-
|
132
|
-
```erb
|
133
|
-
<%= render partial: 'experimental/links' %>
|
134
|
-
<%= render partial: 'experimental/index' %>
|
135
|
-
```
|
136
|
-
|
137
|
-
`app/views/admin/experiments/new.html.erb`
|
138
|
-
|
139
|
-
```erb
|
140
|
-
<%= render partial: 'experimental/links' %>
|
141
|
-
<%= render partial: 'experimental/new' %>
|
142
|
-
```
|
143
|
-
|
144
|
-
*Note: ActiveAdmin users will not need to include the links
|
145
|
-
partials*
|
146
|
-
|
147
18
|
### Subject
|
148
19
|
|
149
20
|
For the class you'd like to be the subject of experiments, include the
|
@@ -276,29 +147,15 @@ You will likely want to automate the running of `rake
|
|
276
147
|
experimental:sync` by adding to your deploy file.
|
277
148
|
|
278
149
|
### Capistrano
|
279
|
-
In `config/deploy.rb`:
|
280
150
|
|
281
|
-
|
282
|
-
|
283
|
-
namespace :database do
|
284
|
-
desc "Sync experiments"
|
285
|
-
task :sync_from_app, roles: :db, only: { primary: true } do
|
286
|
-
run "cd #{current_path} && RAILS_ENV=#{rails_env} bundle exec rake experimental:sync"
|
287
|
-
end
|
288
|
-
end
|
289
|
-
```
|
151
|
+
When you deploy, simply invoke the experimental:sync Rake task to update the
|
152
|
+
experiments in your database from the configuration file:
|
290
153
|
|
291
|
-
Include that in the deploy:default task:
|
292
154
|
```ruby
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
update_code
|
298
|
-
migrate
|
299
|
-
database.sync_from_app
|
300
|
-
restart
|
301
|
-
#...
|
155
|
+
after 'deploy:updated', 'experimental:sync' do
|
156
|
+
on primary :worker do
|
157
|
+
within release_path do
|
158
|
+
rake experimental:sync
|
302
159
|
end
|
303
160
|
end
|
304
161
|
end
|
data/Rakefile
CHANGED
@@ -1,19 +1 @@
|
|
1
|
-
|
2
|
-
require 'bundler/setup'
|
3
|
-
rescue LoadError
|
4
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
-
end
|
6
|
-
|
7
|
-
Bundler::GemHelper.install_tasks
|
8
|
-
|
9
|
-
require 'rake/testtask'
|
10
|
-
|
11
|
-
Rake::TestTask.new(:test) do |t|
|
12
|
-
t.libs << 'lib'
|
13
|
-
t.libs << 'spec'
|
14
|
-
t.pattern = 'spec/**/*_spec.rb'
|
15
|
-
t.verbose = false
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
task :default => :test
|
1
|
+
require 'ritual'
|
data/lib/experimental.rb
CHANGED
@@ -2,12 +2,14 @@ require 'rails'
|
|
2
2
|
require 'experimental/engine'
|
3
3
|
|
4
4
|
module Experimental
|
5
|
-
autoload :
|
6
|
-
autoload :ControllerActions, 'experimental/controller_actions'
|
5
|
+
autoload :Experiment, 'experimental/experiment'
|
7
6
|
autoload :Loader, 'experimental/loader'
|
8
7
|
autoload :Overrides, 'experimental/overrides'
|
8
|
+
autoload :Population, 'experimental/population'
|
9
9
|
autoload :Source, 'experimental/source'
|
10
|
+
autoload :Subject, 'experimental/subject'
|
10
11
|
autoload :Test, 'experimental/test'
|
12
|
+
autoload :VERSION, 'experimental/version'
|
11
13
|
|
12
14
|
class << self
|
13
15
|
def configure(configuration)
|
@@ -2,8 +2,9 @@ module Experimental
|
|
2
2
|
class Experiment < ActiveRecord::Base
|
3
3
|
extend Population::Filter
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
if ActiveRecord::VERSION::MAJOR < 4 || defined?(ProtectedAttributes)
|
6
|
+
attr_accessible :name, :num_buckets, :notes, :population
|
7
|
+
end
|
7
8
|
|
8
9
|
validates_presence_of :name, :num_buckets
|
9
10
|
validates_numericality_of :num_buckets, :greater_than_or_equal_to => 1
|
@@ -11,7 +12,7 @@ module Experimental
|
|
11
12
|
:greater_than_or_equal_to => 0,
|
12
13
|
:less_than => :num_buckets,
|
13
14
|
:if => :ended?
|
14
|
-
validate :
|
15
|
+
validate :validate_dates
|
15
16
|
|
16
17
|
def self.in_code
|
17
18
|
where(:removed_at => nil)
|
@@ -86,9 +87,7 @@ module Experimental
|
|
86
87
|
result = false
|
87
88
|
|
88
89
|
unless removed?
|
89
|
-
result =
|
90
|
-
{ removed_at: Time.now }, without_protection: true
|
91
|
-
)
|
90
|
+
result = update_attribute(:removed_at, Time.now)
|
92
91
|
end
|
93
92
|
|
94
93
|
result
|
@@ -130,15 +129,19 @@ module Experimental
|
|
130
129
|
|
131
130
|
private
|
132
131
|
|
133
|
-
def
|
134
|
-
|
132
|
+
def validate_dates
|
133
|
+
validate_date 'start_date'
|
134
|
+
validate_date 'end_date'
|
135
|
+
end
|
136
|
+
|
137
|
+
def validate_date(attribute)
|
135
138
|
value = read_attribute_before_type_cast(attribute)
|
139
|
+
return if value.blank?
|
136
140
|
begin
|
137
|
-
value.
|
141
|
+
return if value.to_time
|
138
142
|
rescue ArgumentError
|
139
|
-
errors.add(attribute, "is not a valid date")
|
140
143
|
end
|
141
|
-
|
144
|
+
errors.add(attribute, "is not a valid date")
|
142
145
|
end
|
143
146
|
|
144
147
|
def population_filter
|
data/lib/experimental/loader.rb
CHANGED
@@ -13,7 +13,7 @@ module Experimental
|
|
13
13
|
|
14
14
|
Experimental::Experiment.transaction do
|
15
15
|
active = Experimental.experiment_data.map do |name, attributes|
|
16
|
-
experiment = Experimental::Experiment.
|
16
|
+
experiment = Experimental::Experiment.where(name: name).first_or_initialize
|
17
17
|
|
18
18
|
unstarted = attributes.delete('unstarted')
|
19
19
|
defaults = {'num_buckets' => nil, 'notes' => nil, 'population' => nil}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/experimental/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: experimental
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HowAboutWe.com
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-06-
|
15
|
+
date: 2014-06-18 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rails
|
@@ -52,22 +52,16 @@ files:
|
|
52
52
|
- MIT-LICENSE
|
53
53
|
- README.markdown
|
54
54
|
- Rakefile
|
55
|
-
- app/models/experimental/experiment.rb
|
56
|
-
- app/models/experimental/population/default.rb
|
57
|
-
- app/models/experimental/population/filter.rb
|
58
|
-
- app/models/experimental/population/new_users.rb
|
59
|
-
- app/models/experimental/subject.rb
|
60
|
-
- app/views/experimental/_experiment.html.erb
|
61
|
-
- app/views/experimental/_index.html.erb
|
62
|
-
- app/views/experimental/_links.html.erb
|
63
|
-
- app/views/experimental/_new.html.erb
|
64
55
|
- config/routes.rb
|
65
56
|
- lib/experimental.rb
|
66
|
-
- lib/experimental/controller_actions.rb
|
67
57
|
- lib/experimental/engine.rb
|
58
|
+
- lib/experimental/experiment.rb
|
68
59
|
- lib/experimental/loader.rb
|
69
|
-
- lib/experimental/middleware.rb
|
70
60
|
- lib/experimental/overrides.rb
|
61
|
+
- lib/experimental/population.rb
|
62
|
+
- lib/experimental/population/default.rb
|
63
|
+
- lib/experimental/population/filter.rb
|
64
|
+
- lib/experimental/population/new_users.rb
|
71
65
|
- lib/experimental/railtie.rb
|
72
66
|
- lib/experimental/rspec_helpers.rb
|
73
67
|
- lib/experimental/source.rb
|
@@ -75,6 +69,7 @@ files:
|
|
75
69
|
- lib/experimental/source/base.rb
|
76
70
|
- lib/experimental/source/cache.rb
|
77
71
|
- lib/experimental/source/configuration.rb
|
72
|
+
- lib/experimental/subject.rb
|
78
73
|
- lib/experimental/test.rb
|
79
74
|
- lib/experimental/test/cucumber.rb
|
80
75
|
- lib/experimental/test/rspec.rb
|
@@ -110,4 +105,3 @@ signing_key:
|
|
110
105
|
specification_version: 4
|
111
106
|
summary: Adds support for database-backed AB tests in Rails apps
|
112
107
|
test_files: []
|
113
|
-
has_rdoc:
|
@@ -1,16 +0,0 @@
|
|
1
|
-
<tr>
|
2
|
-
<td><%= experiment.name.humanize %></td>
|
3
|
-
<td><%= "#{experiment.num_buckets} (0-#{experiment.num_buckets-1})" %></td>
|
4
|
-
<td><%= experiment.population || "default" %></td>
|
5
|
-
<td><%= experiment.notes.try(:gsub, "\n", '<br>').try(:html_safe) %></td>
|
6
|
-
<td><%= experiment.start_date.try(:in_time_zone).try(:strftime, "%D %r %Z") %></td>
|
7
|
-
<% if @include_inactive %>
|
8
|
-
<td><%= experiment.winning_bucket %></td>
|
9
|
-
<td><%= experiment.end_date.try(:in_time_zone).try(:strftime, "%D %r %Z") %></td>
|
10
|
-
<td><%= experiment.removed_at.try(:in_time_zone).try(:strftime, "%D %r %Z") %></td>
|
11
|
-
<% else %>
|
12
|
-
<td>
|
13
|
-
<%= hidden_field_tag "exp-#{experiment.id}", experiment.id %>
|
14
|
-
<%= select_tag "exp-#{experiment.id}-buckets", options_for_select((0..experiment.num_buckets-1).to_a.insert(0, ['-- select --', -1])), class: 'set_winner' %>
|
15
|
-
</td>
|
16
|
-
<% end %>
|
@@ -1,50 +0,0 @@
|
|
1
|
-
<h1><%= @h1 %></h1>
|
2
|
-
|
3
|
-
<table>
|
4
|
-
<thead>
|
5
|
-
<tr>
|
6
|
-
<th scope="col"> Name </th>
|
7
|
-
<th scope="col"> Buckets </th>
|
8
|
-
<th scope="col"> Population </th>
|
9
|
-
<th scope="col"> Notes </th>
|
10
|
-
<th scope="col"> Start </th>
|
11
|
-
<th scope="col"> Winner </th>
|
12
|
-
<% if @include_inactive %>
|
13
|
-
<th scope="col"> End </th>
|
14
|
-
<th scope="col"> Removed </th>
|
15
|
-
<% end %>
|
16
|
-
</tr>
|
17
|
-
</thead>
|
18
|
-
<tbody>
|
19
|
-
<%= render partial: 'experimental/experiment', collection: @experiments %>
|
20
|
-
</tbody>
|
21
|
-
</table>
|
22
|
-
|
23
|
-
<script type="text/javascript">
|
24
|
-
$(function(){
|
25
|
-
$(".set_winner").change(function(){
|
26
|
-
var bucket_id = $(this).val();
|
27
|
-
var msg = "Are you sure you want to end this experiment and set the winning bucket to " + bucket_id;
|
28
|
-
|
29
|
-
if( bucket_id > -1 && confirm(msg) ){
|
30
|
-
var exp_id = $(this).siblings().val();
|
31
|
-
|
32
|
-
$.ajax({
|
33
|
-
type: "POST",
|
34
|
-
data: {id:exp_id, bucket_id:bucket_id},
|
35
|
-
url: '<%= @experimental_path_names.set_winner %>',
|
36
|
-
success: function(resp){
|
37
|
-
window.location.reload();
|
38
|
-
},
|
39
|
-
error: function(){
|
40
|
-
alert("WE BLEW UP!");
|
41
|
-
$(this).val(-1);
|
42
|
-
}
|
43
|
-
});
|
44
|
-
}
|
45
|
-
else{
|
46
|
-
$(this).val(-1);
|
47
|
-
}
|
48
|
-
});
|
49
|
-
});
|
50
|
-
</script>
|
@@ -1,37 +0,0 @@
|
|
1
|
-
<h1> New Experiment</h1>
|
2
|
-
<br />
|
3
|
-
<%= form_for(@experiment, url: @experimental_path_names.index) do |f| %>
|
4
|
-
<% if @experiment.errors.any? %>
|
5
|
-
<div id="error_explanation">
|
6
|
-
<h2>
|
7
|
-
<%= pluralize(@experiment.errors.count, "error") %>
|
8
|
-
probited this experiment from being saved:
|
9
|
-
</h2>
|
10
|
-
<ul>
|
11
|
-
<% @experiment.errors.full_messages.each do |msg| %>
|
12
|
-
<li><%= msg %></li>
|
13
|
-
<% end %>
|
14
|
-
</ul>
|
15
|
-
</div>
|
16
|
-
<% end %>
|
17
|
-
|
18
|
-
<p class="field">
|
19
|
-
<%= f.label :name %>
|
20
|
-
<br />
|
21
|
-
<%= f.text_field :name %>
|
22
|
-
</p>
|
23
|
-
<p class="field">
|
24
|
-
<%= f.label :num_buckets %>
|
25
|
-
<br />
|
26
|
-
<%= f.text_field :num_buckets %>
|
27
|
-
</p>
|
28
|
-
<p class="field">
|
29
|
-
<%= f.label :notes %>
|
30
|
-
<br />
|
31
|
-
<%= f.text_area :notes, cols: "30", rows: "5" %>
|
32
|
-
</p>
|
33
|
-
|
34
|
-
<p class="actions" >
|
35
|
-
<%= f.submit %>
|
36
|
-
</p>
|
37
|
-
<% end %>
|
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
|
-
module Experimental
|
4
|
-
module ControllerActions
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
class_eval do
|
9
|
-
attr_writer :base_resource_name
|
10
|
-
|
11
|
-
respond_to :json, :only => [:set_winner]
|
12
|
-
|
13
|
-
before_filter :set_experimental_path_names
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def base_resource_name
|
18
|
-
@base_resource_name ||= "experiment"
|
19
|
-
end
|
20
|
-
|
21
|
-
def set_experimental_path_names
|
22
|
-
@experimental_path_names = OpenStruct.new
|
23
|
-
plural_path = "#{base_resource_name.pluralize}_path"
|
24
|
-
|
25
|
-
@experimental_path_names.index = self.send(plural_path.to_sym)
|
26
|
-
if self.respond_to?("inactive_#{plural_path}".to_sym)
|
27
|
-
@experimental_path_names.inactive = self.send("inactive_#{plural_path}".to_sym)
|
28
|
-
end
|
29
|
-
@experimental_path_names.new = self.send("new_#{base_resource_name}_path".to_sym)
|
30
|
-
@experimental_path_names.set_winner = self.send("set_winner_#{plural_path}".to_sym)
|
31
|
-
end
|
32
|
-
|
33
|
-
def experimental_path_names
|
34
|
-
set_experimental_path_names if @experimental_path_names.nil?
|
35
|
-
@experimental_path_names
|
36
|
-
end
|
37
|
-
|
38
|
-
def experiments_index
|
39
|
-
@h1 = "In-progress Experiments"
|
40
|
-
@include_inactive = false
|
41
|
-
@experiments = Experiment.in_progress
|
42
|
-
end
|
43
|
-
|
44
|
-
def experiments_new
|
45
|
-
@experiment = Experiment.new
|
46
|
-
end
|
47
|
-
|
48
|
-
def experiments_create
|
49
|
-
@experiment = Experiment.new(params[:experimental_experiment])
|
50
|
-
@experiment.admin = true
|
51
|
-
@experiment.start_date = Time.now
|
52
|
-
|
53
|
-
if @experiment.save
|
54
|
-
flash[:notice] = "Experiment was successfully created."
|
55
|
-
return true
|
56
|
-
else
|
57
|
-
flash.now[:error] = "There was an error!"
|
58
|
-
return false
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def experiments_inactive
|
63
|
-
@h1 = "Ended or Removed Experiments"
|
64
|
-
@include_inactive = true
|
65
|
-
@experiments = Experiment.ended_or_removed
|
66
|
-
end
|
67
|
-
|
68
|
-
def create
|
69
|
-
if experiments_create
|
70
|
-
redirect_to experimental_path_names.index
|
71
|
-
else
|
72
|
-
render :new
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def inactive
|
77
|
-
experiments_inactive
|
78
|
-
render :index
|
79
|
-
end
|
80
|
-
|
81
|
-
def experiments_set_winner
|
82
|
-
exp = Experiment.find params[:id]
|
83
|
-
if exp.end(params[:bucket_id])
|
84
|
-
render json: nil, status: :ok
|
85
|
-
else
|
86
|
-
render json: nil, status: :error
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|