Module: ConstantTableSaver::ActiveRecord4ClassMethods

Defined in:
lib/constant_table_saver.rb

Instance Method Summary collapse

Instance Method Details

#_to_sql_with_binds(sql, binds) ⇒ Object



188
189
190
191
192
193
194
195
196
# File 'lib/constant_table_saver.rb', line 188

def _to_sql_with_binds(sql, binds)
  if sql.respond_to?(:to_sql)
    # an arel object
    connection.to_sql(sql, binds)
  else
    # a plain string
    sql
  end
end

#find_by_sql(sql, binds = []) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/constant_table_saver.rb', line 156

def find_by_sql(sql, binds = [])
  @find_by_sql ||= {
    :all   => relation.to_sql,
    :id    => relation.where(relation.table[primary_key].eq(connection.substitute_at(columns_hash[primary_key], 0))).limit(1).
                tap {|r| r.bind_values += [[columns_hash[primary_key], :undefined]]}. # work around AR 4.1.9-4.1.x (but not 4.2.x) calling nil.first if there's no bind_values
                arel,
    :first => relation.order(relation.table[primary_key].asc).limit(1).to_sql,
    :last  => relation.order(relation.table[primary_key].desc).limit(1).to_sql,
  }

  if binds.empty?
    _sql = _to_sql_with_binds(sql, binds)

    if _sql == @find_by_sql[:all]
      return @cached_records ||= super(relation.to_sql).each(&:freeze)
    elsif _sql == @find_by_sql[:first]
      return [relation.to_a.first].compact
    elsif _sql == @find_by_sql[:last]
      return [relation.to_a.last].compact
    end

  elsif binds.length == 1 &&
        binds.first.first.is_a?(ActiveRecord::ConnectionAdapters::Column) &&
        binds.first.first.name == primary_key &&
        _to_sql_with_binds(sql, binds) == _to_sql_with_binds(@find_by_sql[:id], binds) # we have to late-render the find(id) SQL because mysql2 on 4.1 and later requires the bind variables to render the SQL, and errors out with a nil dereference otherwise
    @cached_records_by_id ||= relation.to_a.index_by {|record| record.id.to_param}
    return [@cached_records_by_id[binds.first.last.to_param]].compact
  end

  super
end