Class: ComboBox::Generator::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/combo_box/generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(controller, action_name, model, options = {}) ⇒ Base

Returns a new instance of Base


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/combo_box/generator.rb', line 69

def initialize(controller, action_name, model, options={})
  @controller = controller
  @action_name = action_name.to_sym
  @options = (options.is_a?(Hash) ? options : {})
  @model = model
  columns = @options.delete(:columns)
  columns ||= @model.content_columns.collect{|x| x.name.to_sym}.delete_if{|c| [:lock_version, :created_at, :updated_at].include?(c)}
  columns = [columns] unless columns.is_a? Array
  # Normalize columns
  @columns = columns.collect do |c| 
    c = c.to_s.split(/\:/) if [String, Symbol].include? c.class
    c = if c.is_a? Hash
          Column.new(@model, c.delete(:name), c)
        elsif c.is_a? Array
          sliced = c[0].split('.')
          Column.new(@model, sliced[-1], :filter=>c[1], :interpolation_key=>c[2], :through=>sliced[0..-2])
        else
          raise Exception.new("Bad column: #{c.inspect}")
        end
    c
  end
end

Instance Attribute Details

#action_nameObject

Returns the value of attribute action_name


67
68
69
# File 'lib/combo_box/generator.rb', line 67

def action_name
  @action_name
end

#controllerObject

Returns the value of attribute controller


67
68
69
# File 'lib/combo_box/generator.rb', line 67

def controller
  @controller
end

#optionsObject

Returns the value of attribute options


67
68
69
# File 'lib/combo_box/generator.rb', line 67

def options
  @options
end

Instance Method Details

#controller_actionObject


175
176
177
178
179
180
181
# File 'lib/combo_box/generator.rb', line 175

def controller_action()
  code  = "def #{@action_name}\n"
  code << self.controller_code.strip.gsub(/^/, '  ')+"\n"
  code << "end\n"
  # list = code.split("\n"); list.each_index{|x| puts((x+1).to_s.rjust(4)+": "+list[x])}
  return code
end

#controller_codeObject


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/combo_box/generator.rb', line 94

def controller_code()
  foreign_record  = @model.name.underscore
  foreign_records = foreign_record.pluralize
  foreign_records = "many_#{foreign_records}" if foreign_record == foreign_records

  query = []
  parameters = ''
  initial_conditions = ""
  if @options[:conditions].is_a? Hash
    @options[:conditions].each do |key, value| 
      query << (key.is_a?(Symbol) ? @model.table_name+"."+key.to_s : key.to_s)+'=?'
      parameters += ', ' + sanitize_conditions(value)
    end
    initial_conditions = query.join(' AND ').inspect+parameters
  elsif @options[:conditions].is_a? Array
    conditions = @options[:conditions]
    if conditions[0].is_a?(String)  # SQL
      query << conditions[0].to_s
      parameters += ', '+conditions[1..-1].collect{|p| sanitize_conditions(p)}.join(', ') if conditions.size>1
    else
      raise Exception.new("First element of an Array can only be String or Symbol.")
    end
    initial_conditions = query.join(' AND ').inspect+parameters
  elsif @options[:conditions].is_a? String
    initial_conditions = "("+@options[:conditions].gsub(/\s*\n\s*/, ';')+")"
  elsif !@options[:conditions].blank?
    raise ArgumentError.new("Option :conditions can be a Hash, an Array or String (not #{@options[:conditions].class}:#{@options[:conditions].inspect})")
  end
  
  code  = ""
  code << "search, conditions = params[:term], []\n"
  code << "if params[:id].to_i > 0\n"
  code << "  conditions[0] = '#{@model.table_name}.id = ?'\n"
  code << "  conditions << params[:id].to_i\n"
  code << "else\n"
  code << "  words = search.to_s.mb_chars.downcase.strip.normalize.split(/[\\s\\,]+/)\n"
  code << "  if words.size > 0\n"
  code << "    conditions[0] = '('\n"
  code << "    words.each_index do |index|\n"
  code << "      word = words[index].to_s\n"
  code << "      conditions[0] << ') AND (' if index > 0\n"
  if ActiveRecord::Base.connection.adapter_name == "MySQL"
    code << "      conditions[0] << "+@columns.collect{|column| "LOWER(CAST(#{column.sql_name} AS CHAR)) LIKE ?"}.join(' OR ').inspect+"\n"
  else
    code << "      conditions[0] << "+@columns.collect{|column| "LOWER(CAST(#{column.sql_name} AS VARCHAR)) LIKE ?"}.join(' OR ').inspect+"\n"
  end
  code << "      conditions += ["+@columns.collect{|column| column.filter.inspect.gsub('X', '"+word+"').gsub(/(^\"\"\+|\+\"\"\+|\+\"\")/, '')}.join(", ")+"]\n"
  code << "    end\n"
  code << "    conditions[0] << ')'\n"
  code << "  end\n"
  code << "end\n"

  joins = (@options[:joins] ? ".joins(#{@options[:joins].inspect}).includes(#{@options[:joins].inspect})" : "")
  order = (@options[:order] ? ".order(#{@options[:order].inspect})" : ".order("+@columns.collect{|c| "#{c.sql_name} ASC"}.join(', ').inspect+")")
  limit = ".limit(#{@options[:limit]||80})"

  partial = @options[:partial]

  html  = "<ul><% for #{foreign_record} in #{foreign_records} -%><li id='<%=#{foreign_record}.id-%>'>" 
  html << "<% content = item_label_for_#{@action_name}_in_#{@controller.controller_name}(#{foreign_record})-%>"
  if partial
    html << "<%=render(:partial=>#{partial.inspect}, :locals =>{:#{foreign_record}=>#{foreign_record}, :content=>content, :search=>search})-%>"
  else
    html << "<%=highlight(content, search)-%>"
  end
  html << '</li><%end-%></ul>'

  code << "#{foreign_records} = #{@model.name}"
  code << ".where(#{initial_conditions})" unless initial_conditions.blank?
  code << ".where(conditions)"+joins+order+limit+"\n"
  # Render HTML is old Style
  code << "respond_to do |format|\n"
  code << "  format.html { render :inline=>#{html.inspect}, :locals=>{:#{foreign_records}=>#{foreign_records}, :search=>search} }\n"
  code << "  format.json { render :json=>#{foreign_records}.collect{|#{foreign_record}| {:label=>#{item_label(foreign_record)}, :id=>#{foreign_record}.id}}.to_json }\n"
  code << "  format.yaml { render :yaml=>#{foreign_records}.collect{|#{foreign_record}| {'label'=>#{item_label(foreign_record)}, 'id'=>#{foreign_record}.id}}.to_yaml }\n"
  code << "  format.xml  { render :xml=>#{foreign_records}.collect{|#{foreign_record}| {:label=>#{item_label(foreign_record)}, :id=>#{foreign_record}.id}}.to_xml }\n"
  code << "end\n"
  return code
end

#item_label_codeObject


184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/combo_box/generator.rb', line 184

def item_label_code()
  record = 'record'
  code  = "def self.item_label_for_#{@action_name}_in_#{@controller.controller_name}(#{record})\n"
  code << "  if #{record}.is_a? #{@model.name}\n"
  code << "    return #{item_label(record)}\n"
  code << "  else\n"
  code << "    return ''\n"
  code << "  end\n"
  code << "end\n"
  # puts code
  return code
end