ulid-rails 1.0.0 → 1.1.1

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
  SHA256:
3
- metadata.gz: ad104e01d6ca64c2430e444ea5d900dcabf387200d177edf90be642bbebe3eaf
4
- data.tar.gz: 28dc14190454edd67f047908981940d2741fb6cd7da2b416a4631cd0ea651e8d
3
+ metadata.gz: 5af3537525b91e1c92af1b6ea6bdc8a5a872943a1cb5c8d895f50addb0ae7508
4
+ data.tar.gz: 0032d5ad04a924b166bbcf10b1fa9d01a5222aa57175fca0b645dd5df05eee70
5
5
  SHA512:
6
- metadata.gz: f7e03ce00d239548a353a0fb5d1601d8af16303a384fd7c20176065a34a4a3345b8fda3bcc1c18d140858edda8e7544638226037bc2d20c74a1341de3ac62d9d
7
- data.tar.gz: 0c7a894e1124d72608f9e493ce7db594780715c1c0e0a69345970d59b093dcf10bc4bc4b1f21f5db9a48bc4862838cb06851485958b19caa4f8085fb1227eacb
6
+ metadata.gz: 3d2855d4fd84b86d85191104aeee9e8574bf3a29bf095c4fec622c611db9c19694db182476d9bd89c2f78f98193c6b8f2fbadf4045fe6240a0d0f0091f30ff19
7
+ data.tar.gz: 02ebc48788b7d39f5d1684802a2941b10e237d880885c63e311d76493d02f6a5956ba98b54c77c9d54014eec0306ac4df9f91d78324279c621623500bbaf002b
data/.env CHANGED
@@ -1 +1 @@
1
- RUBY_VERSION=2.6
1
+ RUBY_VERSION=2.7
@@ -1,15 +1,20 @@
1
1
  ---
2
2
  name: Linting
3
- on: [push, pull_request]
3
+
4
+ on:
5
+ pull_request:
6
+ push:
7
+ branches:
8
+ - master
9
+ workflow_dispatch:
10
+
4
11
  jobs:
5
12
  standardrb:
6
- env:
7
- AR_VERSION: "5.2"
8
13
  runs-on: ubuntu-latest
9
14
  steps:
10
- - uses: actions/checkout@v2
15
+ - uses: actions/checkout@v3
11
16
  - uses: ruby/setup-ruby@v1
12
17
  with:
13
- ruby-version: 3.0
18
+ ruby-version: "3.1"
14
19
  bundler-cache: true
15
- - run: bundle exec standardrb
20
+ - run: bundle exec rubocop
@@ -1,21 +1,36 @@
1
1
  ---
2
2
  name: Tests
3
- on: [push, pull_request]
3
+
4
+ on:
5
+ pull_request:
6
+ push:
7
+ branches:
8
+ - master
9
+ workflow_dispatch:
10
+
4
11
  jobs:
5
12
  tests:
13
+ name: ActiveRecord ${{ matrix.activerecord-version }} / Ruby ${{ matrix.ruby-version }}
6
14
  runs-on: ubuntu-latest
7
15
  strategy:
16
+ fail-fast: false
8
17
  matrix:
9
- activerecord-version: ["5.0", "5.1", "5.2", "6.0", "6.1"]
10
- ruby-version: ["2.6", "2.7", "3.0"]
18
+ activerecord-version: ["5.0", "5.1", "5.2", "6.0", "6.1", "7.0", "7.0.5"]
19
+ ruby-version: ["2.7", "3.0", "3.1", "3.2"]
11
20
  exclude:
12
- - activerecord-version: "5.0"
13
- ruby-version: "3.0"
14
- - activerecord-version: "5.1"
15
- ruby-version: "3.0"
16
- - activerecord-version: "5.2"
17
- ruby-version: "3.0"
21
+ - {activerecord-version: "5.0", ruby-version: "3.0"}
22
+ - {activerecord-version: "5.0", ruby-version: "3.1"}
23
+ - {activerecord-version: "5.0", ruby-version: "3.2"}
24
+ - {activerecord-version: "5.1", ruby-version: "3.0"}
25
+ - {activerecord-version: "5.1", ruby-version: "3.1"}
26
+ - {activerecord-version: "5.1", ruby-version: "3.2"}
27
+ - {activerecord-version: "5.2", ruby-version: "3.0"}
28
+ - {activerecord-version: "5.2", ruby-version: "3.1"}
29
+ - {activerecord-version: "5.2", ruby-version: "3.2"}
30
+ - {activerecord-version: "6.0", ruby-version: "3.1"}
18
31
  steps:
19
- - uses: actions/checkout@v2
20
- - name: Test ActiveRecord ${{ matrix.activerecord-version }} and Ruby ${{ matrix.ruby-version }}
21
- run: RUBY_VERSION=${{ matrix.ruby-version }} docker-compose run -e AR_VERSION=${{ matrix.activerecord-version }} test
32
+ - uses: actions/checkout@v3
33
+ - run: docker-compose run test
34
+ env:
35
+ RUBY_VERSION: ${{ matrix.ruby-version }}
36
+ AR_VERSION: ${{ matrix.activerecord-version }}
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ require:
2
+ - rubocop-minitest
3
+ - standard
4
+
5
+ inherit_gem:
6
+ rubocop-minitest: config/default.yml
7
+ standard: config/base.yml
8
+
9
+ AllCops:
10
+ NewCops: enable
11
+ Exclude:
12
+ - 'vendor/**/*'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # ulid-rails CHANGELOG
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 1.1.1
6
+
7
+ - Drop support for ruby 2.6.
8
+ - Fix compatibility with ActiveRecord 7.0.5+.
9
+
10
+ ## 1.1.0
11
+
12
+ - Fix eager loading with limit/offset on models that have ulid primary key. The fix only applies to ActiveRecord 5.2, 6 and 7 (#38).
13
+ - Add support for Ruby 3.1.
14
+ - Add support for ActiveRecord 7.
15
+
3
16
  ## 1.0.0
4
17
 
5
18
  - Drop support for Rails 4.2.
@@ -11,6 +24,7 @@
11
24
  ## 0.6.0
12
25
 
13
26
  - Add support for Rails 4.2, 5.0 and 5.1.
27
+ - Known Issue: AREL expressions incorrectly serialize ULID values in Rails 4.2 (#27).
14
28
 
15
29
  ## 0.5.0
16
30
 
data/Gemfile CHANGED
@@ -1,9 +1,2 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in ulid-rails.gemspec
6
- gemspec
7
-
8
1
  version = ENV["AR_VERSION"] || "6.0"
9
2
  eval_gemfile File.expand_path("../gemfiles/#{version}.gemfile", __FILE__)
data/README.md CHANGED
@@ -2,24 +2,28 @@
2
2
 
3
3
  This gem makes it possible to use [ULID](https://github.com/ulid/spec) for DB in a Ruby on Rails app.
4
4
 
5
-
6
5
  ## Installation
7
6
 
8
-
9
7
  ```ruby
10
8
  gem 'ulid-rails'
11
9
  ```
12
10
 
13
11
  And then execute:
14
12
 
15
- $ bundle
13
+ ```
14
+ $ bundle
15
+ ```
16
16
 
17
17
  Or install it yourself as:
18
18
 
19
- $ gem install ulid-rails
19
+ ```
20
+ $ gem install ulid-rails
21
+ ```
20
22
 
21
23
  ## Usage
22
24
 
25
+ First, load up the gem with `require 'ulid/rails'`.
26
+
23
27
  ### Migrations
24
28
 
25
29
  Specify `id: false` to `create_table` and add `id` column as 16-byte binary type.
@@ -27,12 +31,13 @@ Specify `id: false` to `create_table` and add `id` column as 16-byte binary type
27
31
  ```ruby
28
32
  def change
29
33
  create_table :users, id: false do |t|
30
- t.binary :id, limit: 16, primary_key: true
34
+ t.binary :id, limit: 16, auto_generate: true
31
35
  # ...
32
36
  end
33
37
  end
34
38
  ```
35
39
 
40
+ **MySQL note:** You can also declare the `id` column as `t.column :id, 'binary(16)'` when using MySQL, given that the syntax in the example will generate a SQL that makes the id as `VARBINARY(16)` instead of `BINARY(16)`.
36
41
 
37
42
  ### Model Changes
38
43
 
@@ -72,7 +77,7 @@ A virtual column is useful if you want to add index on the timestamp column or w
72
77
 
73
78
  ```ruby
74
79
  create_table :users, id: false do |t|
75
- t.binary :id, limit: 16, primary_key: true
80
+ t.binary :id, limit: 16, auto_generate: true
76
81
  t.datetime :updated_at
77
82
  t.virtual_ulid_timestamp :created_at, :id
78
83
  end
@@ -103,6 +108,41 @@ You need to specicfy `type` option
103
108
  end
104
109
  ```
105
110
 
111
+ ### Many to many associations
112
+
113
+ Please note that this library doesn't work properly with `has_and_belongs_to_many` associations.
114
+
115
+ Our recommendation is to be explicit and instead use the `has_many, through: join_class` association.
116
+ Notice that for it to work properly you must specify the `has_many` to the join class in the main classes of the association,
117
+ and your join class must have `belongs_to` main classes defined as shown in the example below:
118
+
119
+ ```ruby
120
+ class User < ActiveRecord::Base
121
+ include ULID::Rails
122
+ ulid :id, auto_generate: true
123
+
124
+ has_many :user_articles
125
+ has_many :articles, through: :user_articles
126
+ end
127
+
128
+ class UserArticle < ActiveRecord::Base
129
+ include ULID::Rails
130
+ ulid :id, auto_generate: true
131
+ ulid :user_id
132
+ ulid :article_id
133
+
134
+ belongs_to :user
135
+ belongs_to :article
136
+ end
137
+
138
+ class Article < ActiveRecord::Base
139
+ include ULID::Rails
140
+ ulid :id, auto_generate: true
141
+
142
+ has_many :user_articles
143
+ end
144
+ ```
145
+
106
146
  ## Development
107
147
 
108
148
  ### Run tests
@@ -125,6 +165,10 @@ Or run tests locally, without docker-compose
125
165
  $ AR_VERSION=4.2 bundle update && AR_VERSION=4.2 bundle exec rake test
126
166
  ```
127
167
 
168
+ ## Known issues
169
+
170
+ - ActiveRecord 5.0 and 5.1 do not work properly with some data association loading methods. For example, eager loading with limit/offset on a model that has a ulid ID. Refer to test cases that are skiped for AR 5.0 and 5.1.
171
+
128
172
  ## License
129
173
 
130
174
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/docker-compose.yml CHANGED
@@ -1,8 +1,10 @@
1
1
  version: '3.6'
2
2
  services:
3
3
  test:
4
- image: "ruby:${RUBY_VERSION}"
4
+ image: "ruby:${RUBY_VERSION}"
5
5
  command: sh -c "rm -f Gemfile.lock && bundle install && bin/run_tests"
6
+ environment:
7
+ - AR_VERSION=${AR_VERSION}
6
8
  depends_on:
7
9
  pg12:
8
10
  condition: service_healthy
@@ -23,20 +25,20 @@ services:
23
25
  MYSQL_ROOT_PASSWORD: password
24
26
  command: --innodb-large-prefix --innodb-file-format=barracuda
25
27
  healthcheck:
26
- test: mysql --password=password -e "show databases;"
28
+ test: mysql --password=password -e "show databases;"
27
29
  mysql57:
28
30
  image: mysql:5.7
29
31
  environment:
30
32
  MYSQL_ROOT_PASSWORD: password
31
33
  healthcheck:
32
- test: mysql --password=password -e "show databases;"
34
+ test: mysql --password=password -e "show databases;"
33
35
  mysql80:
34
36
  image: mysql:8.0
35
37
  command: --default-authentication-plugin=mysql_native_password
36
38
  environment:
37
39
  MYSQL_ROOT_PASSWORD: password
38
40
  healthcheck:
39
- test: mysql --password=password -e "show databases;"
41
+ test: mysql --password=password -e "show databases;"
40
42
  pg12:
41
43
  image: postgres:12
42
44
  environment:
data/gemfiles/5.0.gemfile CHANGED
@@ -1,6 +1,10 @@
1
- gem "activesupport", "~> 5.0"
2
- gem "activemodel", "~> 5.0"
3
- gem "activerecord", "~> 5.0"
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "activesupport", "~> 5.0.0"
6
+ gem "activemodel", "~> 5.0.0"
7
+ gem "activerecord", "~> 5.0.0"
4
8
  gem "sqlite3", "~> 1.3.6"
5
9
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
6
10
  gem "pg", ">= 0.18", "< 2.0"
data/gemfiles/5.1.gemfile CHANGED
@@ -1,6 +1,10 @@
1
- gem "activesupport", "~> 5.1"
2
- gem "activemodel", "~> 5.1"
3
- gem "activerecord", "~> 5.1"
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "activesupport", "~> 5.1.0"
6
+ gem "activemodel", "~> 5.1.0"
7
+ gem "activerecord", "~> 5.1.0"
4
8
  gem "sqlite3", "~> 1.3", ">= 1.3.6"
5
9
  gem "mysql2", ">= 0.3.18", "< 0.6.0"
6
10
  gem "pg", ">= 0.18", "< 2.0"
data/gemfiles/5.2.gemfile CHANGED
@@ -1,8 +1,10 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "activesupport", "~> 5.2"
4
- gem "activemodel", "~> 5.2"
5
- gem "activerecord", "~> 5.2"
6
- gem "sqlite3", "~> 1.3.6"
7
- gem "mysql2"
8
- gem "pg"
3
+ gemspec path: ".."
4
+
5
+ gem "activesupport", "~> 5.2.0"
6
+ gem "activemodel", "~> 5.2.0"
7
+ gem "activerecord", "~> 5.2.0"
8
+ gem "sqlite3", "~> 1.3", ">= 1.3.6"
9
+ gem "mysql2", ">= 0.4.4", "< 0.6.0"
10
+ gem "pg", ">= 0.18", "< 2.0"
data/gemfiles/6.0.gemfile CHANGED
@@ -1,8 +1,10 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "activesupport", "~> 6.0"
4
- gem "activemodel", "~> 6.0"
5
- gem "activerecord", "~> 6.0"
6
- gem "sqlite3", "~> 1.4.1"
7
- gem "mysql2"
8
- gem "pg"
3
+ gemspec path: ".."
4
+
5
+ gem "activesupport", "~> 6.0.0"
6
+ gem "activemodel", "~> 6.0.0"
7
+ gem "activerecord", "~> 6.0.0"
8
+ gem "sqlite3", "~> 1.4"
9
+ gem "mysql2", ">= 0.4.4"
10
+ gem "pg", ">= 0.18", "< 2.0"
data/gemfiles/6.1.gemfile CHANGED
@@ -1,8 +1,10 @@
1
1
  source "https://rubygems.org"
2
2
 
3
+ gemspec path: ".."
4
+
3
5
  gem "activesupport", "~> 6.1.0"
4
6
  gem "activemodel", "~> 6.1.0"
5
7
  gem "activerecord", "~> 6.1.0"
6
- gem "sqlite3", "~> 1.4.2"
7
- gem "mysql2"
8
- gem "pg"
8
+ gem "sqlite3", "~> 1.4"
9
+ gem "mysql2", "~> 0.5"
10
+ gem "pg", "~> 1.1"
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "activesupport", "~> 7.0.5"
6
+ gem "activemodel", "~> 7.0.5"
7
+ gem "activerecord", "~> 7.0.5"
8
+ gem "sqlite3", "~> 1.4"
9
+ gem "mysql2", "~> 0.5"
10
+ gem "pg", "~> 1.1"
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "activesupport", "~> 7.0.0", "< 7.0.5"
6
+ gem "activemodel", "~> 7.0.0", "< 7.0.5"
7
+ gem "activerecord", "~> 7.0.0", "< 7.0.5"
8
+ gem "sqlite3", "~> 1.4"
9
+ gem "mysql2", "~> 0.5"
10
+ gem "pg", "~> 1.1"
@@ -8,6 +8,46 @@ module ULID
8
8
  as: "FROM_UNIXTIME(CONV(HEX(#{ulid_column_name} >> 80), 16, 10) / 1000.0)"
9
9
  end
10
10
  end
11
+
12
+ module FinderMethods
13
+ def limited_ids_for(relation)
14
+ id_rows = super
15
+ if klass.attribute_types[primary_key].is_a? ULID::Rails::Type
16
+ id_rows.map do |id|
17
+ klass.attribute_types[primary_key].deserialize id
18
+ end
19
+ else
20
+ id_rows
21
+ end
22
+ end
23
+ end
24
+
25
+ module SchemaStatements
26
+ def distinct_relation_for_primary_key(relation) # :nodoc:
27
+ values = columns_for_distinct(
28
+ visitor.compile(relation.table[relation.primary_key]),
29
+ relation.order_values
30
+ )
31
+
32
+ limited = relation.reselect(values).distinct!
33
+ limited_ids = select_rows(limited.arel, "SQL").map(&:last)
34
+
35
+ if relation.klass.attribute_types[relation.primary_key].is_a? ULID::Rails::Type
36
+ limited_ids.map! do |id|
37
+ relation.klass.attribute_types[relation.primary_key].deserialize id
38
+ end
39
+ end
40
+
41
+ if limited_ids.empty?
42
+ relation.none!
43
+ else
44
+ relation.where!(relation.primary_key => limited_ids)
45
+ end
46
+
47
+ relation.limit_value = relation.offset_value = nil
48
+ relation
49
+ end
50
+ end
11
51
  end
12
52
  end
13
53
  end
@@ -23,9 +23,24 @@ module ULID
23
23
  def deserialize(value)
24
24
  return nil if value.nil?
25
25
 
26
- value = value.to_s if value.is_a?(Data)
27
- value = value.unpack1("H*") if value.encoding == Encoding::ASCII_8BIT
28
- value = value[2..-1] if value.start_with?("\\x")
26
+ case adapter
27
+ when "mysql2"
28
+ if value.is_a?(Data)
29
+ value = value.to_s
30
+ elsif value.is_a?(String)
31
+ value = value.unpack1("H*")
32
+ end
33
+ when "postgresql"
34
+ if value.is_a?(Data)
35
+ value = value.to_s
36
+ value = value.unpack1("H*")
37
+ end
38
+ value = value[2..-1] if value.start_with?("\\x")
39
+ when "sqlite3"
40
+ if value.is_a?(Data)
41
+ value = value.to_s
42
+ end
43
+ end
29
44
 
30
45
  value.length == 32 ? @formatter.format(value) : super
31
46
  end
@@ -1,5 +1,5 @@
1
1
  module ULID
2
2
  module Rails
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.1"
4
4
  end
5
5
  end
data/lib/ulid/rails.rb CHANGED
@@ -46,5 +46,13 @@ module ULID
46
46
 
47
47
  ActiveModel::Type.register(:ulid, ULID::Rails::Type)
48
48
  ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Patch::Migrations
49
+ case ActiveRecord::VERSION::MAJOR
50
+ when 5
51
+ ActiveRecord::FinderMethods.prepend(Patch::FinderMethods) unless ActiveRecord::VERSION::MINOR < 2
52
+ when 6
53
+ ActiveRecord::FinderMethods.prepend(Patch::FinderMethods)
54
+ when 7
55
+ ActiveRecord::ConnectionAdapters::SchemaStatements.prepend(Patch::SchemaStatements)
56
+ end
49
57
  end
50
58
  end
data/ulid-rails.gemspec CHANGED
@@ -38,5 +38,6 @@ Gem::Specification.new do |spec|
38
38
  spec.add_development_dependency "bundler"
39
39
  spec.add_development_dependency "rake"
40
40
  spec.add_development_dependency "minitest", "~> 5.0"
41
- spec.add_development_dependency "standard", "~> 1.3.0"
41
+ spec.add_development_dependency "rubocop-minitest"
42
+ spec.add_development_dependency "standard", "~> 1.16.0"
42
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ulid-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazunori Kajihiro
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-11-23 00:00:00.000000000 Z
12
+ date: 2023-05-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ulid
@@ -123,20 +123,34 @@ dependencies:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
125
  version: '5.0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rubocop-minitest
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
126
140
  - !ruby/object:Gem::Dependency
127
141
  name: standard
128
142
  requirement: !ruby/object:Gem::Requirement
129
143
  requirements:
130
144
  - - "~>"
131
145
  - !ruby/object:Gem::Version
132
- version: 1.3.0
146
+ version: 1.16.0
133
147
  type: :development
134
148
  prerelease: false
135
149
  version_requirements: !ruby/object:Gem::Requirement
136
150
  requirements:
137
151
  - - "~>"
138
152
  - !ruby/object:Gem::Version
139
- version: 1.3.0
153
+ version: 1.16.0
140
154
  description: ULID for rails
141
155
  email:
142
156
  - kazunori.kajihiro@gmail.com
@@ -149,6 +163,7 @@ files:
149
163
  - ".github/workflows/lint.yml"
150
164
  - ".github/workflows/test.yml"
151
165
  - ".gitignore"
166
+ - ".rubocop.yml"
152
167
  - ".standard.yml"
153
168
  - CHANGELOG.md
154
169
  - Gemfile
@@ -164,6 +179,8 @@ files:
164
179
  - gemfiles/5.2.gemfile
165
180
  - gemfiles/6.0.gemfile
166
181
  - gemfiles/6.1.gemfile
182
+ - gemfiles/7.0.5.gemfile
183
+ - gemfiles/7.0.gemfile
167
184
  - lib/ulid/rails.rb
168
185
  - lib/ulid/rails/errors.rb
169
186
  - lib/ulid/rails/formatter.rb
@@ -195,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
212
  - !ruby/object:Gem::Version
196
213
  version: '0'
197
214
  requirements: []
198
- rubygems_version: 3.2.29
215
+ rubygems_version: 3.4.12
199
216
  signing_key:
200
217
  specification_version: 4
201
218
  summary: ULID for rails