Skip to content

Instantly share code, notes, and snippets.

@Roman2K
Created February 2, 2009 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Roman2K/56972 to your computer and use it in GitHub Desktop.
Save Roman2K/56972 to your computer and use it in GitHub Desktop.
# This is an augmented version of the original `insert!'. In addition to the
# original functionality, it allows for specifying:
#
# - :trigger_validation: whether to trigger validation after the record has
# been instantiated. Default: false.
#
# - :inhibit_callbacks: whether to inhibit callbacks supposed to be triggered
# after validation. Default: true.
#
# Also, now, any attribute can be assigned, regardless of their being declared
# as `read_only'.
#
# Details about the concept and the original version at:
# http://roman.flucti.com/painless-record-creation-with-activerecord
#
def insert!(model, attributes={}, options={})
attributes = attributes.stringify_keys
trigger_validation = options.fetch(:trigger_validation, false)
inhibit_callbacks = options.fetch(:inhibit_callbacks, !trigger_validation)
begin
record = model.new { |record| record.send(:attributes=, attributes, false) }
if inhibit_callbacks
def record.callback(*args)
end
end
if trigger_validation
record.valid?
end
record.save(false)
rescue ActiveRecord::StatementInvalid
if $!.message =~ /Column '(.+?)' cannot be null/
unless attributes.key?($1)
attributes[$1] = record.column_for_attribute($1).number? ? 0 : "-"
retry
end
end
raise
end
return record
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment