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