ar_virtual_field 0.7.0 → 0.9.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
  SHA256:
3
- metadata.gz: 8c391b47a216fd9d3f4d88fded8000f516eb80cf8bcec72261ae11aba4db36da
4
- data.tar.gz: b2c66124f49c5ab41911619a6bb035dda7654c221b8968bbba37625ad0137351
3
+ metadata.gz: d7a9c50d5fa5be76b750cd68d22f5fe8ca0c15e2eb88c099c5d73b6a2b728815
4
+ data.tar.gz: 6801aa54d664672c35977025215fd5d1c00f030c2f1c3ddc78ba2d54a72aea15
5
5
  SHA512:
6
- metadata.gz: e7ff29785eeef3a6b1b1b77f7711fe0fb776304d7ab7e6f7b70028cd07f7be8d81a1b6b289c82a7be3ac852c4e41baea0cbe6f1be58a2e9ff68e1a9bde7a672a
7
- data.tar.gz: fd45c9a488e01424d808e6b16647419eb74dc5a3094159ccce1992745f94bf03723da47849a6abe8d9bb851304d3e50949bfcbc42fe3957cbe0c2a72cd9ccb42
6
+ metadata.gz: '09e2c21db4d2d3d9ea91056ba87d355a6c2ff27a2a4c9119182164bf5f201c76602ef9bc28f9298497fee79c56b50010f8adf4523fde81e7a1c65a4d9c8e3799'
7
+ data.tar.gz: d99b66f81f0ea83605448fe246bb432a3cdb93db4a4d80eeecbe3a92836ff44ef701482b8d2bf3669a1ac2e9d8ab80245e7315daf66f03f1203ef4bc3aa3ccb8
data/README.md CHANGED
@@ -39,12 +39,12 @@ Example:
39
39
  class User < ApplicationRecord
40
40
  virtual_field :total_orders,
41
41
  scope: -> { joins(:orders).group(:id) },
42
- select: -> { "COUNT(orders.id)" },
42
+ select: "COUNT(orders.id)",
43
43
  get: -> { orders.count },
44
44
  default: 0
45
45
 
46
46
  virtual_field :fullname,
47
- select: -> { "name || surname" },
47
+ select: "name || surname",
48
48
  get: -> { "#{name}#{surname}" }
49
49
  end
50
50
 
@@ -52,7 +52,7 @@ users_with_orders = User.with_total_orders # queries database once
52
52
 
53
53
  user = users_with_orders.first
54
54
  user.total_orders # => value computed by database
55
- user.fullname # => value computed by database
55
+ user.fullname # => value computed by ruby
56
56
  ```
57
57
 
58
58
  ### Scopes and querying:
@@ -60,12 +60,9 @@ user.fullname # => value computed by database
60
60
  - `with_#{name}`: Automatically generated scope to include the virtual field in queries. You can use this scope in your ActiveRecord queries like so:
61
61
 
62
62
  ```ruby
63
- User.with_total_orders.where(ArVirtualField[:total_orders] => 5)
63
+ User.with_total_orders.where(User.virtual_fields[:total_orders].eq(5))
64
64
  ```
65
65
 
66
- > [!WARNING]
67
- > `ArVirtualField[]` doesn't sanitize its value itself, this example relies on `#where` sanitation, use with caution
68
-
69
66
  This will include the total_orders virtual field in the SQL query and allow filtering by it.
70
67
 
71
68
  ## Contributing
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ArVirtualField
4
- VERSION = "0.7.0"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -21,11 +21,21 @@ module ArVirtualField
21
21
  end
22
22
  end
23
23
 
24
- def self.[](field)
25
- Arel.sql(HelperMethods.table_with_column(field))
24
+ class FieldsData < Hash
25
+ def [](field)
26
+ statement = super(field.to_sym)
27
+ raise "Unknown virtual field `#{field}`" unless statement
28
+ statement.()
29
+ end
30
+ end
31
+
32
+ def virtual_fields
33
+ @ar_virtual_fields || FieldsData.new
26
34
  end
27
35
 
28
36
  def virtual_field(name, scope: nil, select:, get:, default: nil)
37
+ @ar_virtual_fields ||= FieldsData.new
38
+
29
39
  name = name.to_s
30
40
  current_class = self
31
41
  unwrap_arel_expression = -> (exp) { exp.is_a?(Arel::Nodes::NodeExpression) ? exp : Arel.sql(exp) }
@@ -40,6 +50,8 @@ module ArVirtualField
40
50
  end
41
51
 
42
52
  if scope
53
+ @ar_virtual_fields[name.to_sym] = -> { Arel.sql(HelperMethods.table_with_column(name)) }
54
+
43
55
  scope_name = :"_scope_#{name}"
44
56
 
45
57
  scope(scope_name, scope)
@@ -51,10 +63,16 @@ module ArVirtualField
51
63
 
52
64
  HelperMethods.select_append(joins(<<~SQL.squish), "#{HelperMethods.table_with_column(name)} AS #{name}")
53
65
  LEFT JOIN (#{scope_query.to_sql}) #{HelperMethods.table_name(name)}
54
- ON #{HelperMethods.table_name(name)}.id = #{table_name}.id
66
+ ON #{
67
+ Array(primary_key).map do |pk|
68
+ "#{HelperMethods.table_name(name)}.#{pk} = #{table_name}.#{pk}"
69
+ end.join(' AND')
70
+ }
55
71
  SQL
56
72
  end)
57
73
  else
74
+ @ar_virtual_fields[name.to_sym] = -> { select_lambda.() }
75
+
58
76
  scope(:"with_#{name}", -> do
59
77
  HelperMethods.select_append(self, select_lambda.().as(name))
60
78
  end)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar_virtual_field
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Egorov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-17 00:00:00.000000000 Z
11
+ date: 2024-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 6.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  description: Adds .virtual_field method to make it easy to define virtual fields
28
56
  email:
29
57
  - moonmeander47@ya.ru