Class: LikeQuery::Collect

Inherits:
Object
  • Object
show all
Defined in:
lib/like_query/collect.rb

Instance Method Summary collapse

Constructor Details

#initialize(limit = nil) ⇒ Collect

Initializes the collector. Sets global result limit (falls back to Rails config), and prepares internal state for data, schemas, images, and URLs.



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

def initialize(limit = nil)
  if limit
    @limit = limit
  elsif Rails.configuration.x.like_query.limit
    @limit = Rails.configuration.x.like_query.limit
  else
    @limit = nil
  end
  @length = 0
  @data = {}
  @overflow = false
  @columns_count = 0
  @sub_records_columns_count = 0
  @image = false
  @start_time = Time.now
  @schemes = {}
  @images = {}
  @urls = {}
  @no_action = {}
end

Instance Method Details

#collect(output_schema = nil, extra_attributes: [], limit: nil, parent: nil, image: nil, url: nil) { ... } ⇒ Boolean

Queries records and adds them to the result set for AutoSelect.svelte.

Examples:

Basic usage

c.collect([:title, :number], extra_attributes: [:id_code]) { MyModel.like(f, [:title]) }

Parameters:

  • output_schema (Array<Symbol>, nil) (defaults to: nil)

    Columns shown as rec.values in the dropdown table. Also included in rec.attributes (named). Supports dot-notation and Hash form.

  • extra_attributes (Array<Symbol>) (defaults to: [])

    Extra model columns/methods added only to rec.attributes (not displayed in the table, but returned to the caller on row click).

  • limit (Integer, nil) (defaults to: nil)

    Per-call result cap. Bounded by the global limit from #initialize.

  • parent (Symbol, nil) (defaults to: nil)

    A belongs_to association name. Groups child records under their parent row (+rec.children+). Requires the parent schema to be set via #set_schema.

  • image (Symbol, nil) (defaults to: nil)

    Method name on the record that returns an image URL (+rec.image+).

  • url (Proc, nil) (defaults to: nil)

    proc { |record| path(record) } — result stored as rec.url.

Yields:

  • Block must return an ActiveRecord relation (the query).

Returns:

  • (Boolean)

    false if the global limit is already reached, true otherwise.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
117
118
119
120
# File 'lib/like_query/collect.rb', line 51

def collect(output_schema = nil, extra_attributes: [], limit: nil, parent: nil, image: nil, url: nil, &block)

  _limit = (limit ? (@limit && @limit < limit ? @limit : limit) : @limit)
  return false if @length >= _limit
  length = 0

  recs = yield.includes(parent).limit(_limit)

  scm = (output_schema.present? ? output_schema : recs.like_query_schema)
  if scm.present?
    @schemes[recs.klass.to_s] = schema_to_hash(scm)
  end
  model_name = recs.klass.to_s
  schema = @schemes[model_name] || schema_to_hash(nil)

  _img = image || schema[:image]
  if _img.present?
    @images[model_name] = _img
    @image = true
  end

  _url = url || @urls[model_name]
  if url.present?
    @urls[model_name] = url
  end

  if parent
    parent_assoc = recs.klass.reflect_on_association(parent)
    if !parent_assoc
      raise "parent «#{parent}» is not a valid association"
    end
  end

  recs.each do |rec|

    if @length >= _limit
      @overflow = true
      break
    else

      if parent
        parent_record = rec.send(parent)
        r = record_to_hash(rec, schema, image, parent_record, url: _url, extra_attributes: extra_attributes)
        parent_class_name = parent_record.class.to_s
        parent_key = "#{parent_class_name}#{parent_record.id}"

        unless @data[parent_key]
          parent_schema = @schemes[parent_class_name]
          unless parent_schema
            Rails.logger.debug("WARNING: NO SCHEMA GIVEN FOR «#{parent_class_name}»")
            parent_schema = schema_to_hash(nil)
          end
          @data[parent_key] = record_to_hash(parent_record, parent_schema, @images[parent_class_name], url: @urls[parent_class_name])
          @length += 1
        end
        @data[parent_key][:children] ||= []
        @data[parent_key][:children].push(r)
      else
        r = record_to_hash(rec, schema, image, url: _url, extra_attributes: extra_attributes)
        @data["#{rec.class}#{rec.id}"] = r
      end
      c = (@image ? 1 : 0) + r[:values].to_a.length
      @columns_count = c if c > @columns_count
      @length += 1
      length += 1
    end
  end

  true
end

#generate_hashObject

Returns the full result hash for JSON serialization. Includes data records, total count, overflow flag, column counts, and elapsed time.



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/like_query/collect.rb', line 124

def generate_hash
  data = @data.map { |_, v| v }
  {
    data: data,
    length: @length,
    overflow: @overflow,
    columns_count: @columns_count,
    sub_records_columns_count: @sub_records_columns_count,
    image: @image,
    # sub_records_image: @sub_records_image,
    time: Time.now - @start_time
  }
end

#generate_jsonObject

Serializes generate_hash to a JSON string.



139
140
141
# File 'lib/like_query/collect.rb', line 139

def generate_json
  generate_hash.to_json
end

#set_schema(model, schema = nil, url: nil, no_action: false) ⇒ Object

Pre-registers a schema, URL, and no_action flag for a given model class. Use before collect when the model won't be the primary query target (e.g. parent records).



29
30
31
32
33
# File 'lib/like_query/collect.rb', line 29

def set_schema(model, schema = nil, url: nil, no_action: false)
  @schemes[model.to_s] = schema_to_hash(schema)
  @urls[model.to_s] = url if url
  @no_action[model.to_s] = no_action
end