Module: ActiveRecordPatchFirstOrCreate

Defined in:
lib/active_record_patch_first_or_create.rb,
lib/active_record_patch_first_or_create/version.rb,
lib/active_record_patch_first_or_create/arel_query_creator.rb

Defined Under Namespace

Classes: ArelQueryCreator

Constant Summary collapse

VERSION =
"1.1.1"

Class Method Summary collapse

Class Method Details

.first_or_create(relation, attributes, tries = nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/active_record_patch_first_or_create.rb', line 5

def self.first_or_create relation, attributes, tries=nil

  attributes = attributes.merge(relation.where_values_hash)
  attributes = attributes.merge(rails_timestamps(relation))
  attributes = serialize_columns(relation, attributes)

  begin
    ActiveRecord::Base.connection.execute(ArelQueryCreator.new(relation, attributes).to_sql)
  # Rescue first time that gives RecordNotUnique because:
  # http://www.postgresql.org/message-id/[email protected]
  rescue ActiveRecord::RecordNotUnique
  end

  relation.first
end

.rails_timestamps(relation) ⇒ Object



21
22
23
24
# File 'lib/active_record_patch_first_or_create.rb', line 21

def self.rails_timestamps relation
  time = Time.now
  { created_at: time, updated_at: time }.keep_if { |key| relation.klass.column_names.include?(key.to_s) }
end

.serialize_columns(relation, attributes) ⇒ Object



26
27
28
29
30
31
# File 'lib/active_record_patch_first_or_create.rb', line 26

def self.serialize_columns relation, attributes
  Hash[attributes.map do |key, value|
    column = relation.klass.columns.find { |c| c.name == key.to_s }
    [key, column ? column.cast_type.type_cast_for_database(value) : value]
  end]
end