active_record_patch_first_or_create 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5478264fa26b04687d1f600cec8ebcf8c26cf68
4
- data.tar.gz: 26c207ae53c67c8b4b128d5c7d81aeeac0e598f8
3
+ metadata.gz: b56bc4e68ceb6b1ae6089c20fe56b25d324497fa
4
+ data.tar.gz: 7d90a7e02899bee82c47cf3f260998b6cfb7ec11
5
5
  SHA512:
6
- metadata.gz: 7742d1e4bc569d0288d14bb27e64755acacac0718edc1355efc5003ec31cecf6859c4e23bc61b8c4c2dac4705edcb6b8592d19c07a1bb87ed50d11613f57cb2a
7
- data.tar.gz: 125ae54308548403d7ef4993f5ae457c786a55f94314ceb0a2e93fe237e7889ec9c11f572439e6eefe63e3ffe53997220352bfc6731bd596b9d438a978e3aa5e
6
+ metadata.gz: 391e2fe0cf2643db27a2cd3e4bff5d470b396f9f5e529aae934f64d8055f87ce4417383aaeffcb6e525f51b4627fbdfcdd942a709cee8adf32af07a0d24966e7
7
+ data.tar.gz: de16600866569f8b6ee9f409ee49046fbfeab5a6641a0b0eddd50cf05e7264906bbdce2845002031cb2fb1129dd43e35f0792c7663912b3ee871a9fc8bbd7f86
data/README.md CHANGED
@@ -26,15 +26,19 @@ We find out that methods like first_or_create or find_or_create_by are not atomi
26
26
 
27
27
  Finds the first record with the given attributes, or creates a record with the attributes if one is not found:
28
28
 
29
+ ```ruby
29
30
  # Find the first user with uid "abc123" or create a new one.
30
31
  User.where(uid: 'abc123').atomic_first_or_create(name: 'John', uid: 'abc123')
31
32
  # => #<User id: 1, uid: "abc123", name: 'John'>
32
-
33
+ ```
34
+ ```ruby
33
35
  # Find the first user with uid "abc123" or create a new one.
34
36
  # We already have one so the existing record will be returned.
35
37
  User.where(uid: 'abc123').atomic_first_or_create(name: 'John', uid: 'abc123')
36
38
  # => #<User id: 1, uid: "abc123", name: 'John'>
37
-
39
+ ```
40
+ ```ruby
38
41
  # Find the first user with uid "abc1234" or create a new one
39
42
  User.where(uid: 'abc123').atomic_first_or_create(name: 'Johansson', uid: 'abc1234')
40
43
  # => #<User id: 2, uid: "abc1234", name: 'Johansson'>
44
+ ```
@@ -20,9 +20,9 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.5"
22
22
  spec.add_development_dependency "rake", "~> 0"
23
- spec.add_development_dependency "minitest"
24
- spec.add_development_dependency "mocha"
25
- spec.add_development_dependency "webmock"
26
- spec.add_development_dependency "activerecord"
27
- spec.add_development_dependency "sqlite3"
23
+ spec.add_development_dependency "minitest", "~> 0"
24
+ spec.add_development_dependency "mocha", "~> 0"
25
+ spec.add_development_dependency "webmock", "~> 0"
26
+ spec.add_development_dependency "activerecord", "~> 0"
27
+ spec.add_development_dependency "sqlite3", "~> 0"
28
28
  end
@@ -1,16 +1,14 @@
1
1
  require "active_record_patch_first_or_create/version"
2
+ require "active_record_patch_first_or_create/arel_query_creator"
2
3
 
3
4
  module ActiveRecordPatchFirstOrCreate
4
5
  def self.first_or_create relation, attributes
6
+
5
7
  attributes = attributes.merge(relation.where_values_hash)
6
8
  attributes = attributes.merge(rails_timestamps(relation))
7
9
  attributes = serialize_columns(relation, attributes)
8
10
 
9
- sql = "INSERT INTO #{relation.table_name} (#{attributes.keys.join(",")})
10
- SELECT #{(['?'] * attributes.values.count).join(', ')}
11
- WHERE NOT EXISTS (#{relation.select('1').to_sql})"
12
-
13
- relation.klass.find_by_sql([sql] + attributes.values)
11
+ ActiveRecord::Base.connection.execute(ArelQueryCreator.new(relation, attributes).to_sql)
14
12
 
15
13
  relation.first
16
14
  end
@@ -22,9 +20,8 @@ module ActiveRecordPatchFirstOrCreate
22
20
 
23
21
  def self.serialize_columns relation, attributes
24
22
  Hash[attributes.map do |key, value|
25
- serializer = relation.klass.serialized_attributes[key.to_s]
26
- value = serializer.dump(value) unless serializer.nil?
27
- [key, value]
23
+ column = relation.klass.columns.find { |c| c.name == key.to_s }
24
+ [key, column ? column.cast_type.type_cast_for_database(value) : value]
28
25
  end]
29
26
  end
30
27
  end
@@ -35,4 +32,4 @@ module ActiveRecord
35
32
  ActiveRecordPatchFirstOrCreate.first_or_create(self, attributes)
36
33
  end
37
34
  end
38
- end
35
+ end
@@ -0,0 +1,42 @@
1
+ module ActiveRecordPatchFirstOrCreate
2
+ class ArelQueryCreator < Struct.new(:relation, :attributes)
3
+ def to_sql
4
+ insert_query.to_sql
5
+ end
6
+
7
+ private
8
+
9
+ def insert_query
10
+ manager = Arel::InsertManager.new(ActiveRecord::Base)
11
+ manager.into table
12
+
13
+ attributes.keys.each do |name|
14
+ manager.columns << table[name]
15
+ end
16
+
17
+ manager.select select_query
18
+ manager
19
+ end
20
+
21
+ def select_query
22
+ select = Arel::SelectManager.new(ActiveRecord::Base)
23
+ attributes.values.each do |value|
24
+ select.project Arel.sql(ActiveRecord::Base.connection.quote(value))
25
+ end
26
+ select.where(not_exists_query.exists.not)
27
+ select
28
+ end
29
+
30
+ def not_exists_query
31
+ query = table.project(Arel.sql('1'))
32
+ relation.where_values_hash.each do |k,v|
33
+ query.where(table[k.to_sym].eq(v))
34
+ end
35
+ query
36
+ end
37
+
38
+ def table
39
+ Arel::Table.new relation.table_name
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordPatchFirstOrCreate
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_patch_first_or_create
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - NDrive DevOps Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-12 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,70 +42,70 @@ dependencies:
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mocha
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: webmock
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: activerecord
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: sqlite3
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description: This patch provides first_or_create method to be atomic, once the default
@@ -122,6 +122,7 @@ files:
122
122
  - Rakefile
123
123
  - active_record_patch_first_or_create.gemspec
124
124
  - lib/active_record_patch_first_or_create.rb
125
+ - lib/active_record_patch_first_or_create/arel_query_creator.rb
125
126
  - lib/active_record_patch_first_or_create/version.rb
126
127
  homepage: http://www.ndrive.com
127
128
  licenses:
@@ -143,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
144
  version: '0'
144
145
  requirements: []
145
146
  rubyforge_project:
146
- rubygems_version: 2.2.0
147
+ rubygems_version: 2.4.3
147
148
  signing_key:
148
149
  specification_version: 4
149
150
  summary: ActiveRecord patch first_or_create atomic version