Module: ROM::Plugins::Relation::SQL::AutoRestrictions

Defined in:
lib/rom/plugins/relation/sql/auto_restrictions.rb

Overview

Generates methods for restricting relations by their indexed attributes

Examples:

rom = ROM.container(:sql, 'sqlite::memory') do |config|
  config.create_table(:users) do
    primary_key :id
    column :email, String, null: false, unique: true
  end

  config.plugin(:sql, relations: :auto_restrictions)

  config.relation(:users) do
    schema(infer: true)
  end
end

# now `by_email` is available automatically
rom.relations[:users].by_email('[email protected]')

Class Method Summary collapse

Class Method Details

.apply(target) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



33
34
35
36
37
38
39
40
# File 'lib/rom/plugins/relation/sql/auto_restrictions.rb', line 33

def self.apply(target, **)
  methods, mod = AutoRestrictions.restriction_methods(registry.schemas.canonical(target))

  target.class_eval do
    include(mod)
    methods.each { |meth| auto_curry(meth) }
  end
end

.restriction_methods(schema) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rom/plugins/relation/sql/auto_restrictions.rb', line 43

def self.restriction_methods(schema)
  mod = Module.new

  methods = schema.indexes.each_with_object([]) do |index, generated|
    next if index.partial?

    attributes = index.to_a
    meth_name = :"by_#{attributes.map(&:name).join("_and_")}"

    next if generated.include?(meth_name)

    mod.module_eval do
      if attributes.size == 1
        attribute = attributes[0]

        define_method(meth_name) do |value|
          where(attribute.is(value))
        end
      else
        indexed_attributes = attributes.map.with_index.to_a

        define_method(meth_name) do |*values|
          where(indexed_attributes.map { |attr, idx| attr.is(values[idx]) }.reduce(:&))
        end
      end
    end

    generated << meth_name
  end

  [methods, mod]
end