Module: Ardm::ActiveRecord::Relation

Extended by:
ActiveSupport::Concern
Defined in:
lib/ardm/active_record/relation.rb

Constant Summary collapse

VALID_FIND_OPTIONS =

def apply_finder_options(options)

return super if options.nil? || options.empty?
options = options.dup
conditions = options.slice!(*::ActiveRecord::SpawnMethods::VALID_FIND_OPTIONS)
super(options).where(conditions)

end

[ :conditions, :include, :joins, :limit, :offset, :extend,
:order, :select, :readonly, :group, :having, :from, :lock ]

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *a, &b) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ardm/active_record/relation.rb', line 160

def method_missing(meth, *a, &b)
  if a.empty? && association = reflect_on_association(meth.to_sym)
    case association.macro
    when :belongs_to
      association.klass.where(klass.primary_key => self.select(association.foreign_key))
    when :has_many, :has_one
      association.klass.where(association.foreign_key => self.clone)
    end
  else
    super
  end
end

Instance Method Details

#all(options = {}) ⇒ Object



48
49
50
# File 'lib/ardm/active_record/relation.rb', line 48

def all(options={})
  apply_finder_options(options)
end

#apply_finder_options(options) ⇒ Object

We used to just patch this, like above, but we need to copy it over completely for rails4 since it no longer supports the old style finder methods that act more like the datamapper finders.



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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ardm/active_record/relation.rb', line 65

def apply_finder_options(options)
  relation = clone
  return relation if options.nil?

  finders = options.dup
  finders[:select] = finders.delete(:fields)
  conditions = finders.slice!(*VALID_FIND_OPTIONS)

  finders.delete_if { |key, value| value.nil? && key != :limit }

  ([:joins, :select, :group, :order, :having, :limit, :offset, :from, :lock, :readonly] & finders.keys).each do |finder|
    relation = relation.send(finder, finders[finder])
  end

  conditions.each do |key, value|
    if assoc = relation.reflect_on_association(key)
      conditions.delete(key)
      # strip out assocations
      case assoc.macro
      when :belongs_to
        id = value.is_a?(Hash) ? value.with_indifferent_access[:id] : value
        relation = if value.is_a?(::ActiveRecord::Relation)
                     if value.values.empty?
                       relation.where.not(assoc.foreign_key => nil)
                     else
                       relation.where(assoc.foreign_key => value)
                     end
                   else
                     relation.where(assoc.foreign_key => id)
                   end
      when :has_one
        foreign_class = assoc.options[:class_name].constantize
        foreign_key   = assoc.foreign_key
        parent_key    = assoc.options[:child_key] || klass.primary_key

        if value.is_a?(::Array) && value.empty?
          # @fixme: dm basically no-ops cause it knows you are stupid
          return klass.where(klass.primary_key => nil)
        end

        relation = if value.is_a?(::ActiveRecord::Base)
                     relation.where(parent_key => value.send(assoc.foreign_key))
                   elsif value.is_a?(::ActiveRecord::Relation)
                     relation.where(parent_key => value.select(foreign_key))
                   elsif value.nil?
                     relation.where.not(parent_key => foreign_class.select(foreign_key).where.not(foreign_key => value))
                   else
                     relation.where(parent_key => foreign_class.select(foreign_key).where(value))
                   end
      when :has_many
        foreign_class = assoc.options[:class_name].constantize
        foreign_key   = assoc.foreign_key
        parent_key    = assoc.options[:child_key] || klass.primary_key

        relation = if value.is_a?(::ActiveRecord::Relation)
                     relation.where(foreign_key => value)
                   else
                     relation.where(parent_key => foreign_class.select(foreign_class.primary_key).where.not(foreign_key => value))
                   end
      else
        raise("unknown: #{assoc.inspect}")
      end
    end
  end

  processed_conditions = {}

  conditions.each do |key, value|
    key = key.is_a?(Ardm::Property) ? key.name : key

    case key
    when String, Symbol then
      processed_conditions[key] = value
    when Ardm::Query::Operator then
      relation = key.to_arel(self, value).scope
    else raise "unknown key: #{key.inspect} #{value.inspect}"
    end
  end

  relation = relation.where(processed_conditions) if processed_conditions.any?
  relation = relation.where(finders[:conditions]) if options.has_key?(:conditions)
  relation = relation.includes(finders[:include]) if options.has_key?(:include)
  relation = relation.extending(finders[:extend]) if options.has_key?(:extend)

  relation
end

#calculate(operation, column_name, options = {}) ⇒ Object



153
154
155
156
157
158
# File 'lib/ardm/active_record/relation.rb', line 153

def calculate(operation, column_name, options={})
  if property = properties[column_name]
    column_name = property.field
  end
  super(operation, column_name, options)
end

#destroy!Object



173
174
175
# File 'lib/ardm/active_record/relation.rb', line 173

def destroy!
  delete_all
end