Class: YiffSpace::Search::QueryDSL

Inherits:
Object
  • Object
show all
Defined in:
lib/yiffspace/search/query_dsl.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(relation) ⇒ QueryDSL

param, field, type/proc, Proc(relation)


9
10
11
12
13
14
15
# File 'lib/yiffspace/search/query_dsl.rb', line 9

def initialize(relation)
  @relation = relation
  @fields = []
  @associations = []
  @no_id = false
  @no_dates = false
end

Instance Attribute Details

#associationsObject

Returns the value of attribute associations.



6
7
8
# File 'lib/yiffspace/search/query_dsl.rb', line 6

def associations
  @associations
end

#fieldsObject

Returns the value of attribute fields.



6
7
8
# File 'lib/yiffspace/search/query_dsl.rb', line 6

def fields
  @fields
end

#no_datesObject

Returns the value of attribute no_dates.



6
7
8
# File 'lib/yiffspace/search/query_dsl.rb', line 6

def no_dates
  @no_dates
end

#no_idObject

Returns the value of attribute no_id.



6
7
8
# File 'lib/yiffspace/search/query_dsl.rb', line 6

def no_id
  @no_id
end

#relationObject

Returns the value of attribute relation.



6
7
8
# File 'lib/yiffspace/search/query_dsl.rb', line 6

def relation
  @relation
end

Instance Method Details

#association(*args, **kwargs) ⇒ Object

attribute, class, dsl, join


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
# File 'lib/yiffspace/search/query_dsl.rb', line 59

def association(*args, **kwargs)
  if args.any?
    attribute = args.first
    as = args.second || attribute
    ref = relation.reflect_on_association(attribute)
    raise("Association #{attribute} does not exist on #{relation.name}") if ref.nil?

    klass = ref.klass
    dsl = klass.query_dsl.build
    @associations << [as, klass, dsl, attribute]
    user_class = YiffSpace.config.user_class
    user(as, attribute) if klass == user_class && @fields.none? { |f| f.second == association_column(attribute) }
  elsif kwargs.any?
    attribute = kwargs.delete(:as)
    to_array = lambda { |h|
      k, v = h.first
      [k, v.is_a?(Hash) ? to_array.call(v) : v].flatten
    }
    through = to_array.call(kwargs)
    attribute ||= through.last
    klass = relation
    through.each { |k| klass = klass.reflect_on_association(k).klass }
    dsl = klass.query_dsl.build
    join = through.reverse.reduce { |acc, key| { key => acc } }
    @associations << [attribute, klass, dsl, join]
  else
    raise(ArgumentError, "Missing association")
  end
  self
end

#buildObject



102
103
104
105
106
107
108
109
110
# File 'lib/yiffspace/search/query_dsl.rb', line 102

def build
  @fields << %i[id id integer] if @fields.none? { |field| field.first == :id }
  @fields << %i[created_at created_at datetime] if @fields.none? { |field| field.first == :created_at } && relation.attribute_names.include?("created_at")
  @fields << %i[updated_at updated_at datetime] if @fields.none? { |field| field.first == :updated_at } && relation.attribute_names.include?("updated_at")
  {
    fields:       fields,
    associations: associations,
  }
end

#custom(param, proc, not: false, multi: false, &block) ⇒ Object



17
18
19
20
# File 'lib/yiffspace/search/query_dsl.rb', line 17

def custom(param, proc, not: false, multi: false, &block)
  @fields << [param, nil, proc, block, { not: binding.local_variable_get(:not), multi: multi }]
  self
end

#field(param, db_field = param, type = nil, not: false, multi: false, wildcard: false, like: false, ilike: false, normalize: nil, &block) ⇒ Object



22
23
24
25
26
# File 'lib/yiffspace/search/query_dsl.rb', line 22

def field(param, db_field = param, type = nil, not: false, multi: false, wildcard: false, like: false, ilike: false, normalize: nil, &block)
  type ||= QueryHelper.get_column(db_field, relation.table_name)..type
  @fields << [param, db_field, type, block, { not: binding.local_variable_get(:not), multi: multi, wildcard: wildcard, like: like, ilike: ilike, normalize: normalize }]
  self
end

#no_dates!Object



96
97
98
99
100
# File 'lib/yiffspace/search/query_dsl.rb', line 96

def no_dates!
  @no_dates = true
  @fields.reject! { |field| %i[created_at updated_at].include?(field.first) }
  self
end

#no_id!Object



90
91
92
93
94
# File 'lib/yiffspace/search/query_dsl.rb', line 90

def no_id!
  @no_id = true
  @fields.reject! { |field| field.first == :id }
  self
end

#present(param, db_field = param) ⇒ Object



54
55
56
# File 'lib/yiffspace/search/query_dsl.rb', line 54

def present(param, db_field = param, &)
  field(param, db_field, :present, &)
end

#user(param, association = nil, not: false) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/yiffspace/search/query_dsl.rb', line 28

def user(param, association = nil, not: false, &)
  if param.is_a?(Array)
    raise(ArgumentError, "You must specify an association when passing an array of parameters") if association.nil?
  else
    association ||= param
    param = [:"#{param}_id", :"#{param}_name"]
  end

  case association
  when Symbol, String
    association = association.to_sym
    associations = relation.reflect_on_all_associations(:belongs_to).map(&:name)
    if associations.include?(association)
      column = association_column(association)
    else
      column = association
    end
  when Array
    column = association.first
    association = association.second
  end
  field(param.first, column, not: binding.local_variable_get(:not), &) if param.first
  custom(param.second, ->(q, v) { q.user_name_matches(association, v) }, not: binding.local_variable_get(:not), &) if param.second
  self
end