diff --git a/README.md b/README.md index 821a747..932c179 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ user.fullname # => value computed by database - `with_#{name}`: Automatically generated scope to include the virtual field in queries. You can use this scope in your ActiveRecord queries like so: ```ruby -User.with_total_orders.where(total_orders: 5) +User.with_total_orders.where(ArVirtualField[:total_orders] => 5) ``` This will include the total_orders virtual field in the SQL query and allow filtering by it. diff --git a/ar_virtual_field.gem b/ar_virtual_field.gem index 79f6b03..d6191ff 100644 Binary files a/ar_virtual_field.gem and b/ar_virtual_field.gem differ diff --git a/lib/ar_virtual_field.rb b/lib/ar_virtual_field.rb index fd24c0f..785ce78 100644 --- a/lib/ar_virtual_field.rb +++ b/lib/ar_virtual_field.rb @@ -1,4 +1,6 @@ -# frozen_string_literal: true +# frozen_string_litera: true + +require "active_record" module ArVirtualField module HelperMethods @@ -9,6 +11,18 @@ def self.select_append(relation, *values) relation.select(*values) end + + def self.table_name(name) + "#{name}_outer" + end + + def self.table_with_column(name) + "#{name}_outer.#{name}" + end + end + + def self.[](field) + Arel.sql(HelperMethods.table_with_column(field)) end def virtual_field(name, scope: nil, select:, get:, default: nil) @@ -31,9 +45,14 @@ def virtual_field(name, scope: nil, select:, get:, default: nil) scope(scope_name, scope) scope(:"with_#{name}", -> do - scope_query = current_class.send(scope_name).select(select_lambda.().as(name), "#{table_name}.id") - new_scope = joins("LEFT JOIN (#{scope_query.to_sql}) #{name}_outer ON #{name}_outer.id = #{table_name}.id") - HelperMethods.select_append(new_scope, "#{name}_outer.#{name} AS #{name}") + scope_query = current_class + .send(scope_name) + .select(select_lambda.().as(name), "#{table_name}.id") + + HelperMethods.select_append(joins(<<~SQL.squish), "#{HelperMethods.table_with_column(name)} AS #{name}") + LEFT JOIN (#{scope_query.to_sql}) #{HelperMethods.table_name(name)} + ON #{HelperMethods.table_name(name)}.id = #{table_name}.id + SQL end) else scope(:"with_#{name}", -> do diff --git a/lib/ar_virtual_field/version.rb b/lib/ar_virtual_field/version.rb index 58dd65b..f4e96b7 100644 --- a/lib/ar_virtual_field/version.rb +++ b/lib/ar_virtual_field/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ArVirtualField - VERSION = "0.4.0" + VERSION = "0.5.0" end