Class: Oaken::Loader

Inherits:
Object
  • Object
show all
Defined in:
lib/oaken/loader.rb

Defined Under Namespace

Classes: Type

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lookup_paths: nil, locator: Type, provider: Oaken::Stored::ActiveRecord, context: Oaken::Seeds) ⇒ Loader

Returns a new instance of Loader.



11
12
13
14
15
# File 'lib/oaken/loader.rb', line 11

def initialize(lookup_paths: nil, locator: Type, provider: Oaken::Stored::ActiveRecord, context: Oaken::Seeds)
  @setup = nil
  @lookup_paths, @locator, @provider, @context = Array(lookup_paths).dup, locator, provider, context
  @defaults = {}.with_indifferent_access
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



8
9
10
# File 'lib/oaken/loader.rb', line 8

def context
  @context
end

#locatorObject (readonly)

Returns the value of attribute locator.



8
9
10
# File 'lib/oaken/loader.rb', line 8

def locator
  @locator
end

#lookup_pathsObject (readonly)

Returns the value of attribute lookup_paths.



8
9
10
# File 'lib/oaken/loader.rb', line 8

def lookup_paths
  @lookup_paths
end

#providerObject (readonly)

Returns the value of attribute provider.



8
9
10
# File 'lib/oaken/loader.rb', line 8

def provider
  @provider
end

Instance Method Details

#defaults(**defaults) ⇒ Object

Allow assigning defaults across types.



25
# File 'lib/oaken/loader.rb', line 25

def defaults(**defaults) = @defaults.merge!(**defaults)

#defaults_for(*keys) ⇒ Object



26
# File 'lib/oaken/loader.rb', line 26

def defaults_for(*keys)  = @defaults.slice(*keys)

#definition_location(start_frame:) ⇒ Object



86
87
88
89
90
# File 'lib/oaken/loader.rb', line 86

def definition_location(start_frame:)
  # Locate first frame not in `setup` phase. Rely on caller adjusting frame start to skip over their stack levels.
  # Won't skip over helpers defined in non-setup seed files, though that's probably ok.
  caller_locations(1 + start_frame, 4).find { !setup_files.member? _1.path }
end

#glob(identifier) ⇒ Object



82
83
84
# File 'lib/oaken/loader.rb', line 82

def glob(identifier)
  Pathname.glob lookup_paths.map { File.join _1, "#{identifier}{,/**/*}.rb" }
end

#load_seedObject

Mirrors ‘bin/rails db:seed`.



57
58
59
# File 'lib/oaken/loader.rb', line 57

def load_seed
  Rails.application.load_seed
end

#register(type, as: nil) ⇒ Object

Register a model class via Oaken.loader.context. Note: Oaken’s auto-register means you don’t need to call register often yourself.

register 
register ::Job
register ::Job::Task

Oaken uses ‘name.tableize.tr(“/”, “_”)` for the method names, so they’re accounts, account_jobs, and account_job_tasks, respectively.

You can also pass an explicit as: option:

register User, as: :something_else


45
46
47
48
# File 'lib/oaken/loader.rb', line 45

def register(type, as: nil)
  stored = provider.new(self, type)
  context.define_method(as || type.name.tableize.tr("/", "_")) { stored }
end

#replant_seedObject

Mirrors ‘bin/rails db:seed:replant`.



51
52
53
54
# File 'lib/oaken/loader.rb', line 51

def replant_seed
  ActiveRecord::Tasks::DatabaseTasks.truncate_all
  load_seed
end

#seed(*identifiers) ⇒ Object

Set up a general seed rule or perform a one-off seed for a test file.

You can set up a general seed rule in db/seeds.rb like this:

Oaken.seed :accounts # Seeds from `db/seeds/accounts{,/**/*}.rb` and `db/seeds/<Rails.env>/accounts{,/**/*}.rb`

Then if you need a test specific scenario, we recommend putting them in db/seeds/test/cases.

Say you have db/seeds/test/cases/pagination.rb, you can load it like this:

# test/integration/pagination_test.rb
class PaginationTest < ActionDispatch::IntegrationTest
  setup { seed "cases/pagination" }
end


75
76
77
78
79
80
# File 'lib/oaken/loader.rb', line 75

def seed(*identifiers)
  setup

  identifiers.flat_map { glob _1 }.each { load_one _1 }
  self
end

#test_setupObject



28
29
30
# File 'lib/oaken/loader.rb', line 28

def test_setup
  Oaken::TestSetup.new self
end

#with(**overrides) ⇒ Object

Instantiate a new loader with all its attributes and any specified overrides. See #new for defaults.

Oaken.loader.with(root: "test/fixtures") # `root` returns "test/fixtures" here


20
21
22
# File 'lib/oaken/loader.rb', line 20

def with(**overrides)
  self.class.new(lookup_paths:, locator:, provider:, context:, **overrides)
end