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

Extended by:
Notifications::Listener
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

.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.

rubocop:disable Metrics/AbcSize



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
75
# File 'lib/rom/plugins/relation/sql/auto_restrictions.rb', line 44

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