module RearHelpers::InstanceMixin

Attributes

column[RW]
item[RW]
item_id[RW]
items[R]

Public Instance Methods

__rear__() click to toggle source
# File lib/rear/helpers/generic.rb, line 64
def __rear__
  self.class
end
associated_model_controller(model) click to toggle source
# File lib/rear/helpers/generic.rb, line 59
def associated_model_controller model
  (@__rear__associated_model_controllers ||= {})[model] ||=
    RearUtils.associated_model_controller(model, :ensure_mounted)
end
assocs(*types) click to toggle source
# File lib/rear/helpers/generic.rb, line 28
def assocs *types
  return __rear__.assocs if types.empty?
  types.inject({}) do |assocs,type|
    assocs.merge(__rear__.assocs[type.to_sym] || {})
  end
end
attrs(column, scope) click to toggle source
# File lib/rear/helpers/columns.rb, line 30
def attrs column, scope
  meth = '%s_attrs' % scope
  column_attrs = column.send(meth)
  return column_attrs if column_attrs.any?
  __rear__.send(meth)
end
columns() click to toggle source
# File lib/rear/helpers/columns.rb, line 24
def columns
  @__rear__columns ||= __rear__.columns.inject([]) do |columns,(name, type, attrs, proc)|
    columns << RearInput.new(name, type, attrs, @brand_new_item, &proc)
  end
end
decorative_filter?(name, comparison_function = FILTERS__DECORATIVE_CMP)
Alias for: filter
dom_id() click to toggle source
# File lib/rear/helpers/generic.rb, line 11
def dom_id
  @__rear__dom_id ||= (params[:dom_id] || # params[:dom_id] are used by decorative filters
    (@reverse_assoc ? @reverse_assoc.dom_id : 'rear_element_%s' % self.__id__)).freeze
end
editor_columns() click to toggle source
# File lib/rear/helpers/columns.rb, line 20
def editor_columns
  @__rear__editor_columns ||= columns.select {|c| c.editor?}
end
filter(name, comparison_function = FILTERS__DECORATIVE_CMP) click to toggle source
# File lib/rear/helpers/filters.rb, line 53
def filter name, comparison_function = FILTERS__DECORATIVE_CMP
  ((opted_filters[name] || {})[comparison_function] || []).first
end
Also aliased as: filter?, decorative_filter?
filter?(name, comparison_function = FILTERS__DECORATIVE_CMP)
Alias for: filter
filter_setup_to_options(setup) click to toggle source
# File lib/rear/helpers/filters.rb, line 132
def filter_setup_to_options(setup)
  options = setup[:proc] ? self.instance_exec(&setup[:proc]) : {}
  if options.is_a?(Array)
    options.flatten!
    options = Hash[options.zip(options)]
  end
  return options if options.is_a?(Hash)
  warn "
  %s#%s filter expects options to be provided as a Hash or Array or via a block.
  If block given, it should return a Hash or Array
  " % [self.class, setup[:label]]
  {}
end
filters() click to toggle source
# File lib/rear/helpers/filters.rb, line 4
def filters
  __rear__.filters
end
filters_query_map() click to toggle source
# File lib/rear/helpers/filters.rb, line 49
def filters_query_map
  @@__rear__filters__query_map ||= FILTERS__QUERY_MAP.call(__rear__.orm)
end
filters_to_sql() click to toggle source
# File lib/rear/helpers/filters.rb, line 59
def filters_to_sql
  conditions, sql_chunks, values = {}, [], []
  
  quick_filters.each_pair do |column,filters|
    next unless label = opted_quick_filters[column]
    filters.each_pair do |filter,(query_formats,value)|
      next unless label == filter
      sql_chunks  << query_formats.first % RearUtils.quote_column(model, column)
      values << ([TrueClass, FalseClass, Regexp].include?(value.class) ? value : query_formats.last % value)
    end
  end

  opted_filters.each_pair do |column, setups|
    setups.each_pair do |cmp, (value, query_formats, filter_setup)|
      next if filter_setup[:decorative?]
      
      sql_chunk = query_formats.first % RearUtils.quote_column(model, column)
      custom_sql_chunk  = nil

      if filter_setup[:type] == :boolean && FILTERS__STR_TO_BOOLEAN.has_key?(value)
        values << FILTERS__STR_TO_BOOLEAN[value]
      else
        case cmp
        when :in
          values << value
        when :csl # comma separated list
          values << value.to_s.split(',')
        else
          if value.is_a?(Array)
            custom_sql_chunk = []
            value.each do |v|
              custom_sql_chunk << sql_chunk
              values << query_formats.last % v
            end
            custom_sql_chunk = '(' + custom_sql_chunk.join(' OR ') + ')'
          else
            values << query_formats.last % value
          end
        end
      end
      sql_chunks << (custom_sql_chunk || sql_chunk)
    end
  end

  __rear__.internal_filters.each do |m|
    next unless items = self.send(m)
    sql_chunks << filters_query_map[:in].first % pkey
    values     << items.map {|i| i[pkey]}
  end

  sql_chunks.any? ?
    conditions.merge(conditions: [sql_chunks.join(' AND '), *values]) :
    conditions
end
model() click to toggle source
# File lib/rear/helpers/generic.rb, line 16
def model
  __rear__.model
end
opted_filters() click to toggle source

turn {‘date’ => {‘gte’ => ‘foo’, ‘lte’ => ‘bar’}} into {

:date => {
          :gte => ['foo', ['%s >= ?', '%s'] ],
          :lte => ['bar', ['%s <= ?', '%s'] ],
         }

}

# File lib/rear/helpers/filters.rb, line 34
def opted_filters
  @__rear__opted_filters ||= (params[:filters]||{}).inject({}) do |map,s|
    (column = s.first) && (filter = filters[(column = column.to_sym)]).is_a?(Hash) &&
      (setup = s.last).is_a?(Hash) && setup.each_pair do |cmp,v|
        v && v.size > 0 && (query_formats = filters_query_map[(cmp=cmp.to_sym)]) &&
          (filter_setup = filter[cmp]) && (map[column] ||= {})[cmp] = [
            v, # do not typecast to Fixnum cause this will break Hash to query_string conversion
            query_formats,
            filter_setup,
          ]
      end
    map
  end
end
opted_quick_filters() click to toggle source
# File lib/rear/helpers/filters.rb, line 12
def opted_quick_filters
  @__rear__opted_quick_filters ||= begin
    given_filters = params[:quick_filters] || {}
    quick_filters.inject({}) do |map,(column,*)|
      (v = given_filters[column.to_s]) && v.size > 0 ? map.merge(column => v) : map
    end
  end
end
options(*args) click to toggle source

used for cosmetic compatibility between filters and columns. columns block are executed inside Column instance, and using ‘options` method to define options for :select/:radio/:checkbox columns. filters of these types also uses a block and it is executed in controller’s context. so adding this method here will allow to use ‘options` method inside filter’s block.

@example

filter :colors do
  options 'Red', 'Green', 'Blue'
end
# this is equivalent to
filter :colors do
  ['Red', 'Green', 'Blue']
end
# but looks cosmetically better cause uses same syntax as columns
# File lib/rear/helpers/generic.rb, line 55
def options *args
  args
end
order_params() click to toggle source
# File lib/rear/helpers/order.rb, line 25
def order_params
  @__rear__order_params ||= pane_columns.inject({}) do |map,column|
    (vector = sortable_vector?(column)) ?
      map.update(column.string_name => vector) : map
  end.freeze
end
order_params_to_sql() click to toggle source
# File lib/rear/helpers/order.rb, line 32
def order_params_to_sql
  order = []
  order_params.each_pair do |column_name, vector|
    next unless column = columns.find {|c| c.string_name == column_name}
    case __rear__.orm
    when :dm
      column.order_by.each {|c| order << c.send(vector)}
    when :ar
      columns = column.order_by.map {|c| RearUtils.quote_ar_column(model, c)}
      order  << [columns.join(', '), vector].join(' ')
    end
  end
  order.any? ? order : nil
end
orm() click to toggle source
# File lib/rear/helpers/generic.rb, line 7
def orm
  @__rear__orm ||= RearORM.new(__rear__.model, __rear__.pkey)
end
pager_filters() click to toggle source
# File lib/rear/helpers/pager.rb, line 24
def pager_filters
  @__rear__pager_filters ||= filters.inject({}) do |map,(column, setups)|
    setups.each do |comparison_function, setup|
      (value = filter?(column, comparison_function)) &&
        (map[column] ||= {})[comparison_function] = value
    end
    map
  end
end
pager_linker(page, label = nil) click to toggle source
# File lib/rear/helpers/pager.rb, line 4
def pager_linker page, label = nil
  label ||= page
  url = route(action, *action_params__array, pager_params(page))
  return link_to(url, label) unless xhr?
  
  onclick = "Rear.switch_page('#%s', '%s');" % [dom_id, url]
  link_to nil, label, onclick: onclick
end
pager_params(page = nil, filters = nil) click to toggle source
# File lib/rear/helpers/pager.rb, line 13
def pager_params page = nil, filters = nil
  page.is_a?(Hash) && (filters = page) && (page = nil)
  page ||= params[:page]
  {
             page: page.to_s,
          filters: filters || pager_filters,
    quick_filters: opted_quick_filters,
            order: order_params
  }.reject {|k,v| v.nil? || v.empty?}
end
pane_columns() click to toggle source
# File lib/rear/helpers/columns.rb, line 4
def pane_columns
  @__rear__pane_columns ||= begin
    pane_columns = columns.select {|c| c.pane?}
    [RearInput.new(pkey)] + case action_name
    when :reverse_assoc
      (assoc_columns = __rear__.assoc_columns) ?
        pane_columns.select {|c| assoc_columns.include? c.name} :
        pane_columns[0..1]
    when :quickview
      pane_columns[0..0]
    else
      pane_columns
    end
  end
end
path_to_rear_templates(*chunks) click to toggle source
# File lib/rear/helpers/render.rb, line 18
def path_to_rear_templates *chunks
  template  = File.join *chunks.map(&:to_s)
  locations = []
  {
    @__rear__templates_path => File.join(app.root, @__rear__templates_path.to_s),
    @__rear__templates_fullpath => @__rear__templates_fullpath,
  }.select {|k,v| k}.each_value do |prefix|
    locations << File.join(prefix, EUtils.class_to_route(self.class.model)) if self.class.respond_to?(:model)
    locations << File.join(prefix, 'shared-templates')
  end
  locations << PATH__TEMPLATES
  locations.each do |p|
    fp = File.join(p, template)
    return explicit_view_path(fp) if File.file?(fp)
  end
  raise ArgumentError, '%s template not found in any of %s paths' % [template,locations*', ']
end
pkey() click to toggle source
# File lib/rear/helpers/generic.rb, line 24
def pkey
  __rear__.pkey
end
quick_filter?(column) click to toggle source
# File lib/rear/helpers/filters.rb, line 21
def quick_filter? column
  opted_quick_filters[column]
end
quick_filters() click to toggle source
# File lib/rear/helpers/filters.rb, line 8
def quick_filters
  __rear__.quick_filters
end
readonly?() click to toggle source
# File lib/rear/helpers/generic.rb, line 68
def readonly?
  self.class.readonly?
end
reander(*args, &proc) click to toggle source
# File lib/rear/helpers/render.rb, line 4
def reander *args, &proc
  reander_layout(:layout) { render_slim args, &proc }
end
reander_l(path, *rest, &proc)
Alias for: reander_layout
reander_layout(path, *rest, &proc) click to toggle source
# File lib/rear/helpers/render.rb, line 13
def reander_layout path, *rest, &proc
  render_slim_l path_to_rear_templates('%s.slim' % path), *rest, &proc
end
Also aliased as: reander_l
reander_p(path, *rest)
Alias for: reander_partial
reander_partial(path, *rest) click to toggle source
# File lib/rear/helpers/render.rb, line 8
def reander_partial path, *rest
  render_slim_p path_to_rear_templates('%s.slim' % path), *rest
end
Also aliased as: reander_p
render_column(column, scope) click to toggle source
# File lib/rear/helpers/columns.rb, line 45
def render_column column, scope
  template, value = %w[template value].map {|m| column.send('%s_%s' % [scope, m])}
  locals = if column.optioned?
    options = column.options
    options = Hash[options.zip(options)] if options.is_a?(Array)
    active_options = self.instance_exec(&column.active_options)
    active_options = [active_options] unless active_options.is_a?(Array)
    {options: options, active_options: active_options}
  else
    {value: self.instance_exec(&value)}
  end
  template.is_a?(Proc) ?
    self.instance_exec(&template) :
    render_slim_p(locals) { template_cache(path_to_rear_templates template) }
end
render_editor_column(column) click to toggle source
# File lib/rear/helpers/columns.rb, line 41
def render_editor_column column
  render_column column, :editor
end
render_filters() click to toggle source
# File lib/rear/helpers/filters.rb, line 114
def render_filters
  html = assets_mapper(route(:assets), suffix: '-rear').js_tag('xhr')
  main_filters = filters.inject(html) do |html,(column,setups)|
    setups.each_pair do |comparison_function, setup|
      context = {
          name: 'filters[%s][%s]' % [column, comparison_function],
        column: column,
         value: filter(column, comparison_function),
         setup: setup,
         attrs: Hash[setup[:attrs]]
      }
      template = template_cache(path_to_rear_templates(setup[:template]))
      html << render_slim_p(context) { template }
    end
    html << '&nbsp;'
  end
end
render_pane_column(column) click to toggle source
# File lib/rear/helpers/columns.rb, line 37
def render_pane_column column
  render_column column, :pane
end
sequel?() click to toggle source
# File lib/rear/helpers/generic.rb, line 20
def sequel?
  @@__rear__is_sequel ||= RearUtils.orm(model) == :sq
end
sortable_column?(column) click to toggle source
# File lib/rear/helpers/columns.rb, line 61
def sortable_column? column
  if column.name == pkey || column.order_by? ||
    __rear__.real_columns.any? {|(n,t)| n == column.name}
    sortable_vector column
  end
end
sortable_vector(column) click to toggle source

flip-flopping vectors, that’s it, if current vector set to asc this method will return desc, and vice-versa. also it will return UI arrow direction - when vector is asc arrow is down and arrow is up when vector is desc

# File lib/rear/helpers/order.rb, line 8
def sortable_vector column
  vector = ['asc', nil].include?(order_params[column.string_name]) ? 'desc' : 'asc'
  [vector, vector == 'asc' ? 'down' : 'up']
end
sortable_vector?(column) click to toggle source

checks whether ordering is happening by given column and if it is, check whether a valid vector used

# File lib/rear/helpers/order.rb, line 15
def sortable_vector? column
  if vector = (params[:order] || {})[column.string_name]
    valid_sortable_vector? vector
  end
end
template_cache(template) click to toggle source
# File lib/rear/helpers/generic.rb, line 35
def template_cache template
  ((@__rear__template_cache ||= {})[template] ||= {})[File.mtime(template)] ||= File.read(template)
end
valid_sortable_vector?(vector) click to toggle source
# File lib/rear/helpers/order.rb, line 21
def valid_sortable_vector? vector
  vector if vector == 'asc' || vector == 'desc'
end