Class: IWonder::AbTest

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/i_wonder/ab_test.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#skip_file_save=(value) ⇒ Object (writeonly)

Sets the attribute skip_file_save

Parameters:

  • value

    the value to set the attribute skip_file_save to.



4
5
6
# File 'app/models/i_wonder/ab_test.rb', line 4

def skip_file_save=(value)
  @skip_file_save = value
end

Instance Method Details

#ab_test_goals_attributes=(hash) ⇒ Object


These two methods should NOT be needed. For some reason the accepts_nested_attributes_for is not autosaving or deleting associated goals



26
27
28
29
30
31
32
33
34
35
36
# File 'app/models/i_wonder/ab_test.rb', line 26

def ab_test_goals_attributes=(hash)
  hash.each{|key,value|
    goal = self.ab_test_goals.detect{|tg| tg.id == value["id"].to_i}
    goal ||= self.ab_test_goals.build
    goal.attributes = value
    
    if value["_destroy"] =~ /true|1/ or value["_destroy"].is_a?(TrueClass)
      goal.mark_for_destruction
    end
  }
end

#assigned_count(test_group_name) ⇒ Object



89
90
91
# File 'app/models/i_wonder/ab_test.rb', line 89

def assigned_count(test_group_name)
  self.test_group_memberships.where(:test_group_name => test_group_name).count
end

#from_xml(xml) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'app/models/i_wonder/ab_test.rb', line 113

def from_xml(xml)
  [super]
  
  # make sure it's not blank. Then make sure it's a hash. Then Make sure it's symbolized.
  self.options ||= {}
  self.test_group_data ||= {}
  self.options = {} if self.options.is_a?(String)
  self.test_group_data = {} if self.test_group_data.is_a?(String)
  self.options.symbolize_keys!
  self.test_group_data.symbolize_keys!
  
  self.ab_test_goals.each(&:mark_for_destruction)
  
  hash = Hash.from_xml(xml)
  hash["ab_test"]["ab_test_goals"].each{|ab_test_goal_hash|
    ab_test_goal_hash["options"].symbolize_keys!
    self.ab_test_goals.build(ab_test_goal_hash)
  }
end

#get_results_for(test_group_name, ab_test_goal) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/models/i_wonder/ab_test.rb', line 93

def get_results_for(test_group_name, ab_test_goal)
  scoped_test_group_memberships  = self.test_group_memberships.where(:test_group_name => test_group_name).scoped

  if test_applies_to =~ /account/i
    event_membership_key = "account_id"
  elsif test_applies_to =~ /user/i
    event_membership_key = "user_id"
  else
    event_membership_key = "session_id"
  end
  
  scoped_groups_with_events = scoped_test_group_memberships.joins("LEFT JOIN i_wonder_events ON i_wonder_events.#{event_membership_key} = i_wonder_test_group_memberships.member_id")
  
  scoped_groups_with_goal_events = ab_test_goal.add_goal_to_query(scoped_groups_with_events)
  
  scoped_groups_with_goal_events = scoped_groups_with_goal_events.select("COUNT(DISTINCT i_wonder_events.#{event_membership_key}) as count_all")
  
  AbTest.connection.execute(scoped_groups_with_goal_events.to_sql)[0]["count_all"].to_i
end

#has_two_groups_and_a_goalObject



48
49
50
51
52
53
54
55
56
# File 'app/models/i_wonder/ab_test.rb', line 48

def has_two_groups_and_a_goal
  unless test_group_names.length >= 2
    errors.add(:base, "Must have atleast two test groups")
  end
  
  if ab_test_goals.reject(&:marked_for_destruction?).length == 0
    errors.add(:base, "Must have atleast one goal")
  end
end

#remove_deleted_test_goalsObject



38
39
40
41
# File 'app/models/i_wonder/ab_test.rb', line 38

def remove_deleted_test_goals
  ab_test_goals.select(&:marked_for_destruction?).each(&:destroy)
  ab_test_goals.each(&:save)
end

#remove_fileObject



66
67
68
# File 'app/models/i_wonder/ab_test.rb', line 66

def remove_file
  AbTesting::Loader.remove_file_for(self)
end

#save_to_fileObject



59
60
61
62
63
# File 'app/models/i_wonder/ab_test.rb', line 59

def save_to_file
  unless @skip_file_save
    AbTesting::Loader.save_ab_test(self)
  end
end

#started?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'app/models/i_wonder/ab_test.rb', line 70

def started?
  test_group_memberships.count > 0
end

#started_atObject



133
134
135
# File 'app/models/i_wonder/ab_test.rb', line 133

def started_at
  test_group_memberships.minimum(:created_at)
end

#which_test_group?(current_controller) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/i_wonder/ab_test.rb', line 74

def which_test_group?(current_controller)
  if(current_group = get_current_group(current_controller))
    return current_group.test_group_name
  else
    begin
      test_group = add_to_test_group(randomly_chosen_test_group, current_controller)
    rescue Exception => e
      # If there is some error, just return a randome option. Better not to crash
      # TODO: this should warn developer somehow
      return randomly_chosen_test_group
    end
    return test_group.test_group_name
  end
end