Skip to content

Commit

Permalink
Started working on a operation syntax builder.
Browse files Browse the repository at this point in the history
  • Loading branch information
Doug Youch committed May 24, 2010
1 parent 5bca639 commit 51eae04
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 12 deletions.
28 changes: 26 additions & 2 deletions app/controllers/members_controller.rb
Expand Up @@ -208,8 +208,10 @@ def options
@options = self.class.module_options(params[:options])

if request.post? && @options.valid?
Configuration.set_config_model(@options)
flash[:notice] = "Updated Everyone options".t
if params[:commit]
Configuration.set_config_model(@options)
flash[:notice] = "Updated Everyone options".t
end
redirect_to :action => 'index'
return
end
Expand Down Expand Up @@ -241,9 +243,13 @@ def segments
def create_segment
cms_page_path ['People', 'Segments'], 'Create a Segment'

@builder = UserSegment::OperationBuilder.new nil

@segment = UserSegment.new :main_page => true

if request.post? && params[:segment]
return redirect_to :action => 'index' unless params[:commit]

if @segment.update_attributes params[:segment]
@segment.refresh
redirect_to :action => 'segments'
Expand All @@ -256,7 +262,11 @@ def edit_segment

cms_page_path ['People', 'Segments'], '%s Segment' / @segment.name

@builder = UserSegment::OperationBuilder.new nil

if request.post? && params[:segment]
return redirect_to :action => 'index', :path => @segment.id unless params[:commit]

if @segment.update_attributes params[:segment]
if @segment.should_refresh?
@segment.refresh
Expand All @@ -273,10 +283,14 @@ def copy_segment

cms_page_path ['People', 'Segments'], 'Copy %s Segment' / segment_to_copy.name

@builder = UserSegment::OperationBuilder.new nil

@segment = UserSegment.new segment_to_copy.attributes.symbolize_keys.slice(:name, :description, :fields, :main_page, :segment_options_text, :order_by)
@segment.name += ' (Copy)' unless request.post?

if request.post? && params[:segment]
return redirect_to :action => 'index', :path => segment_to_copy.id unless params[:commit]

if @segment.update_attributes params[:segment]
@segment.refresh
redirect_to :action => 'segments'
Expand All @@ -290,6 +304,16 @@ def refresh_segment
redirect_to :action => 'segments'
end

def builder
cms_page_path ['People'], 'Operation Builder'

@builder = UserSegment::OperationBuilder.new nil

if request.post? && params[:builder]
@builder.build(params[:builder])
end
end

def create
cms_page_path ['People'],'Create Contact'

Expand Down
13 changes: 6 additions & 7 deletions app/models/end_user_segment_field.rb
Expand Up @@ -9,12 +9,11 @@ def self.user_segment_fields_handler_info
}
end

register_field :email, UserSegment::CoreType::StringType
register_field :gender, UserSegment::CoreType::StringType
register_field :created, UserSegment::CoreType::DateTimeType, :field => :created_at
register_field :registered, UserSegment::CoreType::BooleanType
register_field :activated, UserSegment::CoreType::BooleanType
register_field :id, UserSegment::CoreType::NumberType
register_field :user_level, UserSegment::CoreType::NumberType
register_field :email, UserSegment::CoreType::StringType, :name => 'User: Email'
register_field :gender, UserSegment::CoreType::StringType, :name => 'User: Gender'
register_field :created, UserSegment::CoreType::DateTimeType, :field => :created_at, :name => 'User: Created'
register_field :registered, UserSegment::CoreType::BooleanType, :name => 'User: Registered'
register_field :activated, UserSegment::CoreType::BooleanType, :name => 'User: Activated'
register_field :user_level, UserSegment::CoreType::NumberType, :name => 'User: User Level'

end
6 changes: 4 additions & 2 deletions app/models/user_segment/field.rb
@@ -1,7 +1,5 @@

class UserSegment::Field < HashModel
include HandlerActions

attributes :field => nil, :operation => nil, :arguments => [], :child => nil

validates_presence_of :field
Expand Down Expand Up @@ -67,6 +65,10 @@ def operation_argument_options
self.operation_info[:argument_options] if self.operation_info
end

def operation_argument_names
self.operation_info[:argument_names] if self.operation_info
end

def operation_info
@operation_info ||= self.type_class.user_segment_field_type_operations[self.operation.to_sym] if self.type_class
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/user_segment/operation.rb
Expand Up @@ -41,7 +41,7 @@ def to_a

def to_expr
output = @operator == 'not' ? 'not ' : ''
output = @fields.collect { |fld| fld.to_expr }.join(' + ')
output += @fields.collect { |fld| fld.to_expr }.join(' + ')
output
end
end
87 changes: 87 additions & 0 deletions app/models/user_segment/operation_builder.rb
@@ -0,0 +1,87 @@

class UserSegment::OperationBuilder < HashModel
attributes :operator => nil, :field => 'created', :operation => 'since', :arguments => []

def operator_options
[['Not', 'not'], ['', nil]]
end

def build(opts={})
self.operator = opts[:operator]
self.field = opts[:field]
self.operation = opts[:operation]
unless self.operation_options.rassoc(self.operation)
self.operation = self.operation_options[0][1]
@user_segment_field = nil
end

self.operation_arguments.each_with_index do |type, idx|
arg = "argument#{idx}"
self.send("#{arg}=", opts[arg.to_sym]) if opts[arg.to_sym]
end
end

def field_options
return @field_options if @field_options
@field_options = []
UserSegment::FieldHandler.handlers.each do |handler|
handler[:class].user_segment_fields.each do |field, values|
@field_options << [values[:name], field.to_s] unless @field_options.rassoc(field.to_s)
end
end
@field_options.sort! { |a, b| a[0] <=> b[0] }
end

def user_segment_field
return @user_segment_field if @user_segment_field
@user_segment_field = UserSegment::Field.new :field => self.field, :operation => self.operation, :arguments => self.arguments
@user_segment_field
end

def operation_options
return @operation_options if @operation_options
@operation_options = []

if self.user_segment_field.type_class
@operation_options = self.user_segment_field.type_class.user_segment_field_type_operations.collect do |operation, values|
[values[:name], operation.to_s]
end
end

@operation_options.sort! { |a, b| a[0] <=> b[0] }
end

def operation_arguments
self.user_segment_field.operation_arguments || []
end

def operation_argument_names
self.user_segment_field.operation_argument_names
end

def operation_argument_options
self.user_segment_field.operation_argument_options
end

def convert_to(value, idx)
UserSegment::FieldType.convert_to(value, self.operation_arguments[idx], self.operation_argument_options[idx])
end

def method_missing(arg, *args)
arg = arg.to_s
if arg =~ /^argument(\d+)$/
self.arguments[$1.to_i]
elsif arg =~ /^argument(\d+)=$/
self.arguments[$1.to_i] = self.convert_to(args[0], $1.to_i) if $1.to_i < self.operation_arguments.length
else
super
end
end

def to_expr
return '' unless self.user_segment_field.valid?
output = self.operator == 'not' ? 'not ' : ''
output += self.user_segment_field.to_expr
output
end
end
30 changes: 30 additions & 0 deletions app/views/members/_operation_form.html.erb
@@ -0,0 +1,30 @@

<div id="operation_builder">
<% admin_form_for :builder, @builder do |f| -%>
<%= f.check_boxes :operator, [['not', 'not']], :single => true, :label => 'I am' %>
<%= f.select :field, @builder.field_options, :label => 'looking for' %>
<%= f.select :operation, @builder.operation_options %>
<% @builder.operation_arguments.each_with_index do |arg, idx| -%>
<% arg_options = @builder.operation_argument_options[idx]
label = @builder.operation_argument_names[idx]
if arg_options[:options] -%>
<%= f.select "argument#{idx}", arg_options[:options], :label => label %>
<% else -%>
<%= f.text_field "argument#{idx}", :label => label %>
<% end -%>
<% end -%>
<%= f.submit 'Build' %>
<% end -%>

<div class="operation">
<span>Expression:</span><br/>
<textarea style="width:400px; height: 50px;" readonly>
<%= @builder.to_expr %>
</textarea>
</div>

</div>


1 change: 1 addition & 0 deletions app/views/members/_segment_form.html.erb
Expand Up @@ -9,3 +9,4 @@
<%= f.spacer %>
<%= f.cancel_submit_buttons 'Cancel', (@segment.id ? 'Save' : 'Create') %>
<% end -%>

3 changes: 3 additions & 0 deletions app/views/members/builder.html.erb
@@ -0,0 +1,3 @@
<%= render :partial => 'operation_form' %>

0 comments on commit 51eae04

Please sign in to comment.