Class: ActiveList::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/active_list/generator/finder.rb,
lib/active_list/generator.rb

Overview

Manage data query

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ Generator

Returns a new instance of Generator.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/active_list/generator.rb', line 8

def initialize(*args, &block)
  options = args.extract_options!
  @controller = options[:controller]
  name = args.shift || @controller.controller_name.to_sym
  model = (options[:model]||name).to_s.classify.constantize
  @collection = !!(model.name == @controller.controller_name.to_s.classify)
  @controller_method_name = "list#{'_'+name.to_s if name != @controller.controller_name.to_sym}"
  @view_method_name       = "_#{@controller.controller_name}_list_#{name}_tag"
  @records_variable_name  = "@#{name}"
  @table = ActiveList::Definition::Table.new(name, model, options)
  if block_given?
    yield @table
  else
    @table.load_default_columns
  end
  @parameters = {:sort => :to_s, :dir => :to_s}
  @parameters.merge!(:page => :to_i, :per_page => :to_i) if @table.paginate?
end

Instance Attribute Details

#controllerObject

Returns the value of attribute controller.



6
7
8
# File 'lib/active_list/generator.rb', line 6

def controller
  @controller
end

#controller_method_nameObject

Returns the value of attribute controller_method_name.



6
7
8
# File 'lib/active_list/generator.rb', line 6

def controller_method_name
  @controller_method_name
end

#records_variable_nameObject

Returns the value of attribute records_variable_name.



6
7
8
# File 'lib/active_list/generator.rb', line 6

def records_variable_name
  @records_variable_name
end

#tableObject

Returns the value of attribute table.



6
7
8
# File 'lib/active_list/generator.rb', line 6

def table
  @table
end

#view_method_nameObject

Returns the value of attribute view_method_name.



6
7
8
# File 'lib/active_list/generator.rb', line 6

def view_method_name
  @view_method_name
end

Instance Method Details

#collection?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/active_list/generator.rb', line 27

def collection?
  @collection
end

#controller_method_codeObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/active_list/generator.rb', line 39

def controller_method_code
  code  = "# encoding: utf-8\n"
  code << "def #{self.controller_method_name}\n"
  code << self.session_initialization_code.dig
  code << "  respond_to do |format|\n"
  code << "    format.html do\n"
  code << "      if request.xhr?\n"
  code << self.renderer.remote_update_code.dig(4)
  code << "      else\n"
  code << "        render(inline: '<%=#{self.view_method_name}-%>')\n" # , layout: action_has_layout?
  code << "      end\n"
  code << "    end\n"
  for format, exporter in ActiveList::Exporters.hash
    code << "    format.#{format} do\n"
    code << exporter.new(self).send_data_code.dig(3)
    code << "    end\n"
  end
  code << "  end\n"
  # Save preferences of user
  if defined? User and User.instance_methods.include? :pref
    code << "  p = current_user.pref('list.#{self.view_method_name}', YAML::dump({}))\n"
    code << "  p.set! YAML::dump(#{var_name(:params)}.stringify_keys)\n"
  end
  code << "end\n"
  # code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}
  unless ::Rails.env.production?
    file = ::Rails.root.join("tmp", "code", "active_list", "controllers", self.controller.controller_path, self.controller_method_name + ".rb")
    FileUtils.mkdir_p(file.dirname)
    File.write(file, code)
  end
  return code
end

#rendererObject



35
36
37
# File 'lib/active_list/generator.rb', line 35

def renderer
  ActiveList::Renderers[@table.options[:renderer]].new(self)
end

#select_data_code(options = {}) ⇒ Object

Generate select code for the table taking all parameters in account



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/active_list/generator/finder.rb', line 7

def select_data_code(options = {})
  paginate = (options.has_key?(:paginate) ? options[:paginate] : @table.paginate?)
  # Check order
  unless @table.options.keys.include?(:order)
    columns = @table.table_columns
    @table.options[:order] = (columns.size > 0 ? columns.first.name.to_sym : {id: :desc}) # "#{@table.model.table_name}.id DESC"
  end

  class_name = @table.model.name
  class_name = "(controller_name != '#{class_name.tableize}' ? controller_name.to_s.classify.constantize : #{class_name})" if self.collection?

  # Find data
  query_code = "#{class_name}"
  query_code << self.scope_code if self.scope_code
  query_code << ".select(#{self.select_code})" if self.select_code
  query_code << ".where(#{self.conditions_code})" unless @table.options[:conditions].blank?
  query_code << ".joins(#{@table.options[:joins].inspect})" unless @table.options[:joins].blank?
  unless self.includes_reflections.empty?
    expr = self.includes_reflections.inspect[1..-2]
    query_code << ".includes(#{expr})"
    query_code << ".references(#{expr})"
  end

  code = ""
  code << "#{var_name(:count)} = #{query_code}.count\n"
  if paginate
    code << "#{var_name(:limit)}  = (#{var_name(:params)}[:per_page] || 25).to_i\n"
    code << "#{var_name(:page)}   = (#{var_name(:params)}[:page] || 1).to_i\n"
    code << "#{var_name(:page)}   = 1 if #{var_name(:page)} < 1\n"
    code << "#{var_name(:offset)} = (#{var_name(:page)} - 1) * #{var_name(:limit)}\n"
    code << "#{var_name(:last)}   = (#{var_name(:count)}.to_f / #{var_name(:limit)}).ceil.to_i\n"
    code << "#{var_name(:last)}   = 1 if #{var_name(:last)} < 1\n"
    code << "return #{self.view_method_name}(options.merge(page: 1)) if 1 > #{var_name(:page)}\n"
    code << "return #{self.view_method_name}(options.merge(page: #{var_name(:last)})) if #{var_name(:page)} > #{var_name(:last)}\n"
  end
  code << "#{self.records_variable_name} = #{query_code}"
  code << ".reorder(#{var_name(:order)})"
  if paginate
    code << ".offset(#{var_name(:offset)})"
    code << ".limit(#{var_name(:limit)})"
  end
  code << " || {}\n"
  return code
end

#session_initialization_codeObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/active_list/generator.rb', line 87

def session_initialization_code
  code  = "options = {} unless options.is_a? Hash\n"
  code << "options.update(params)\n"
  if defined? User and User.instance_methods.include? :pref
    code << "#{var_name(:params)} = YAML::load(current_user.pref('list.#{self.view_method_name}', YAML::dump({})).value).symbolize_keys\n"
    code << "#{var_name(:params)} = {} unless #{var_name(:params)}.is_a?(Hash)\n"
  else
    code << "#{var_name(:params)} = {}\n"
  end
  code << "#{var_name(:params)}.update(options.symbolize_keys)\n"
  code << "unless #{var_name(:params)}[:hidden_columns].is_a? Array\n"
  code << "  #{var_name(:params)}[:hidden_columns] = #{@table.hidden_columns.map(&:name).map(&:to_sym).inspect}\n"
  code << "end\n"
  for parameter, convertor in @parameters.sort{|a,b| a[0].to_s <=> b[0].to_s}
    # expr  = "options.delete('#{@table.name}_#{parameter}') || options.delete('#{parameter}') || #{var_name(:params)}[:#{parameter}]"
    # expr += " || #{@table.options[parameter]}" unless @table.options[parameter].blank?
    # code << "#{var_name(:params)}[:#{parameter}] = (#{expr}).#{convertor}\n"
    expr  = "#{var_name(:params)}[:#{parameter}]"
    expr = "(#{expr} || #{@table.options[parameter]})" unless @table.options[parameter].blank?
    code << "#{var_name(:params)}[:#{parameter}] = #{expr}.#{convertor}\n"
  end
  # Order
  code << "#{var_name(:order)} = #{@table.options[:order] ? @table.options[:order].inspect : 'nil'}\n"
  code << "if #{var_name(:col)} = {" + @table.sortable_columns.collect{|c| "'#{c.sort_id}' => '#{c.sort_expression}'"}.join(', ') + "}[#{var_name(:params)}[:sort]]\n"
  code << "  #{var_name(:params)}[:dir] = 'asc' unless #{var_name(:params)}[:dir] == 'asc' or #{var_name(:params)}[:dir] == 'desc'\n"
  code << "  #{var_name(:order)} = #{var_name(:col)} + ' ' + #{var_name(:params)}[:dir]\n"
  code << "end\n"

  return code
end

#var_name(name) ⇒ Object



31
32
33
# File 'lib/active_list/generator.rb', line 31

def var_name(name)
  "_#{name}"
end

#view_method_codeObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/active_list/generator.rb', line 72

def view_method_code
  code  = "# encoding: utf-8\n"
  code << "def #{self.view_method_name}(options={}, &block)\n"
  code << self.session_initialization_code.dig
  code << self.renderer.build_table_code.dig
  code << "end\n"
  # code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}
  unless ::Rails.env.production?
    file = ::Rails.root.join("tmp", "code", "active_list", "views", self.controller.controller_path, self.view_method_name + ".rb")
    FileUtils.mkdir_p(file.dirname)
    File.write(file, code)
  end
  return code
end