Class: Ransack::Nodes::Condition

Inherits:
Node
  • Object
show all
Defined in:
lib/ransack/nodes/condition.rb

Instance Attribute Summary collapse

Attributes inherited from Node

#context

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

i18n_alias, i18n_word, #initialize, #translate

Constructor Details

This class inherits a constructor from Ransack::Nodes::Node

Instance Attribute Details

#is_default=(value) ⇒ Object (writeonly)

Sets the attribute is_default

Parameters:

  • value

    the value to set the attribute is_default to.



8
9
10
# File 'lib/ransack/nodes/condition.rb', line 8

def is_default=(value)
  @is_default = value
end

#predicateObject

Returns the value of attribute predicate.



7
8
9
# File 'lib/ransack/nodes/condition.rb', line 7

def predicate
  @predicate
end

Class Method Details

.extract(context, key, values) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/ransack/nodes/condition.rb', line 11

def extract(context, key, values)
  attributes, predicate = extract_attributes_and_predicate(key)
  if attributes.size > 0
    combinator = key.match(/_(or|and)_/) ? $1 : nil
    condition = self.new(context)
    condition.build(
      :a => attributes,
      :p => predicate.name,
      :m => combinator,
      :v => predicate.wants_array ? Array(values) : [values]
    )
    # TODO: Figure out what to do with multiple types of attributes, if anything.
    # Tempted to go with "garbage in, garbage out" on this one
    predicate.validate(condition.values, condition.default_type) ? condition : nil
  end
end

Instance Method Details

#arel_predicateObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/ransack/nodes/condition.rb', line 165

def arel_predicate
  predicates = attributes.map do |attr|
    attr.attr.send(predicate.arel_predicate, formatted_values_for_attribute(attr))
  end

  if predicates.size > 1
    case combinator
    when 'and'
      Arel::Nodes::Grouping.new(Arel::Nodes::And.new(predicates))
    when 'or'
      predicates.inject(&:or)
    end
  else
    predicates.first
  end
end

#attributesObject Also known as: a



48
49
50
# File 'lib/ransack/nodes/condition.rb', line 48

def attributes
  @attributes ||= []
end

#attributes=(args) ⇒ Object Also known as: a=



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ransack/nodes/condition.rb', line 53

def attributes=(args)
  case args
  when Array
    args.each do |attr|
      attr = Attribute.new(@context, attr)
      self.attributes << attr if attr.valid?
    end
  when Hash
    args.each do |index, attrs|
      attr = Attribute.new(@context, attrs[:name])
      self.attributes << attr if attr.valid?
    end
  else
    raise ArgumentError, "Invalid argument (#{args.class}) supplied to attributes="
  end
end

#build(params) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/ransack/nodes/condition.rb', line 120

def build(params)
  params.with_indifferent_access.each do |key, value|
    if key.match(/^(a|v|p|m)$/)
      self.send("#{key}=", value)
    end
  end

  self
end

#build_attribute(name = nil) ⇒ Object



104
105
106
107
108
# File 'lib/ransack/nodes/condition.rb', line 104

def build_attribute(name = nil)
  Attribute.new(@context, name).tap do |attribute|
    self.attributes << attribute
  end
end

#build_value(val = nil) ⇒ Object



110
111
112
113
114
# File 'lib/ransack/nodes/condition.rb', line 110

def build_value(val = nil)
  Value.new(@context, val).tap do |value|
    self.values << value
  end
end

#casted_values_for_attribute(attr) ⇒ Object



186
187
188
# File 'lib/ransack/nodes/condition.rb', line 186

def casted_values_for_attribute(attr)
  validated_values.map {|v| v.cast(predicate.type || attr.type)}
end

#combinatorObject Also known as: m



94
95
96
# File 'lib/ransack/nodes/condition.rb', line 94

def combinator
  @attributes.size > 1 ? @combinator : nil
end

#combinator=(val) ⇒ Object Also known as: m=



98
99
100
# File 'lib/ransack/nodes/condition.rb', line 98

def combinator=(val)
  @combinator = ['and', 'or'].detect {|v| v == val.to_s} || nil
end

#default?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/ransack/nodes/condition.rb', line 134

def default?
  @is_default
end

#default_typeObject



199
200
201
# File 'lib/ransack/nodes/condition.rb', line 199

def default_type
  predicate.type || (attributes.first && attributes.first.type)
end

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


142
143
144
145
146
147
148
# File 'lib/ransack/nodes/condition.rb', line 142

def eql?(other)
  self.class == other.class &&
  self.attributes == other.attributes &&
  self.predicate == other.predicate &&
  self.values == other.values &&
  self.combinator == other.combinator
end

#formatted_values_for_attribute(attr) ⇒ Object



190
191
192
193
194
195
196
197
# File 'lib/ransack/nodes/condition.rb', line 190

def formatted_values_for_attribute(attr)
  formatted = casted_values_for_attribute(attr).map do |val|
    val = attr.ransacker.formatter.call(val) if attr.ransacker && attr.ransacker.formatter
    val = predicate.format(val)
    val
  end
  predicate.wants_array ? formatted : formatted.first
end

#hashObject



151
152
153
# File 'lib/ransack/nodes/condition.rb', line 151

def hash
  [attributes, predicate, values, combinator].hash
end

#inspectObject



203
204
205
206
207
208
# File 'lib/ransack/nodes/condition.rb', line 203

def inspect
  data =[['attributes', a.try(:map, &:name)], ['predicate', p], ['combinator', m], ['values', v.try(:map, &:value)]].reject { |e|
    e[1].blank?
  }.map { |v| "#{v[0]}: #{v[1]}" }.join(', ')
  "Condition <#{data}>"
end

#keyObject



138
139
140
# File 'lib/ransack/nodes/condition.rb', line 138

def key
  @key ||= attributes.map(&:name).join("_#{combinator}_") + "_#{predicate.name}"
end

#persisted?Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/ransack/nodes/condition.rb', line 130

def persisted?
  false
end

#predicate_nameObject Also known as: p



160
161
162
# File 'lib/ransack/nodes/condition.rb', line 160

def predicate_name
  predicate.name if predicate
end

#predicate_name=(name) ⇒ Object Also known as: p=



155
156
157
# File 'lib/ransack/nodes/condition.rb', line 155

def predicate_name=(name)
  self.predicate = Predicate.named(name)
end

#valid?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/ransack/nodes/condition.rb', line 40

def valid?
  attributes.detect(&:valid?) && predicate && valid_arity? && predicate.validate(values, default_type) && valid_combinator?
end

#valid_arity?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/ransack/nodes/condition.rb', line 44

def valid_arity?
  values.size <= 1 || predicate.wants_array
end

#validated_valuesObject



182
183
184
# File 'lib/ransack/nodes/condition.rb', line 182

def validated_values
  values.select {|v| predicate.validator.call(v.value)}
end

#valueObject



116
117
118
# File 'lib/ransack/nodes/condition.rb', line 116

def value
  predicate.wants_array ? values.map {|v| v.cast(default_type)} : values.first.cast(default_type)
end

#valuesObject Also known as: v



71
72
73
# File 'lib/ransack/nodes/condition.rb', line 71

def values
  @values ||= []
end

#values=(args) ⇒ Object Also known as: v=



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ransack/nodes/condition.rb', line 76

def values=(args)
  case args
  when Array
    args.each do |val|
      val = Value.new(@context, val)
      self.values << val
    end
  when Hash
    args.each do |index, attrs|
      val = Value.new(@context, attrs[:value])
      self.values << val
    end
  else
    raise ArgumentError, "Invalid argument (#{args.class}) supplied to values="
  end
end