Skip to content

Instantly share code, notes, and snippets.

@copiousfreetime
Created February 16, 2009 21:43
Show Gist options
  • Select an option

  • Save copiousfreetime/65388 to your computer and use it in GitHub Desktop.

Select an option

Save copiousfreetime/65388 to your computer and use it in GitHub Desktop.
#
# This exists as a way to make active record use SQL literals in attributes when
# creating or updating records
#
module ActiveRecord
module ConnectionAdapters
class Column
class Literal < ::String
def quoted_id() self end
end
@@type_cast = instance_method :type_cast
def type_cast( value )
if Literal === value
value
else
@@type_cast.bind( self ).call( value )
end
end
end
end
class Base
def Base.Literal(*args, &block)
::ActiveRecord::ConnectionAdapters::Column::Literal.new(*args, &block)
end
end
def self.Literal(*args, &block)
Base.Literal(*args, &block)
end
end
require 'set'
module Ci
module Extension
module ActiveRecord
module ClassMethods
# force these columns to use DEFAULT on create
def use_db_default_in_columns(*column_names)
column_names.each { |c| db_default_columns << c }
end
def db_default_columns
@db_default_columns ||= Set.new("created_time")
end
end
end
end
end
module ActiveRecord
class Base
before_create :force_default_where_necessary
after_create :reload_if_default_forced
# force the sql keyword DEFAULT into those columns where there must be a
# default value, that is, columns with a default that are not nullable, those
# should have the DEFAULT keyword set
def force_default_where_necessary
@default_forced = false
@attributes.each_pair do |name, value|
unless value
column = column_for_attribute(name)
if self.class.db_default_columns.include?( column.name ) or
(column.has_default? and !column.null) then
send "#{name}=", ActiveRecord::Literal('DEFAULT')
@default_forced = true
end
end
end
end
# if a default was forced, then we have to load the value that was stored in
# the db into the record, AR won't, it'll just leave it as 'DEFAULT' which
# really won't help much.
#
def reload_if_default_forced
if @default_forced then
self.reload
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment