Class: Oaken::Stored::ActiveRecord
- Inherits:
-
Object
- Object
- Oaken::Stored::ActiveRecord
- Defined in:
- lib/oaken/stored/active_record.rb
Instance Attribute Summary collapse
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Instance Method Summary collapse
-
#attributes_for(**attributes) ⇒ Object
Build attributes used for ‘create`/`upsert`, applying loader and per-type `defaults`.
-
#create(label = nil, unique_by: nil, **attributes) ⇒ Object
Create a record in the database with the passed ‘attributes`.
-
#defaults(**attributes) ⇒ Object
Set defaults for all types:.
-
#initialize(loader, type) ⇒ ActiveRecord
constructor
A new instance of ActiveRecord.
-
#label(**labels) ⇒ Object
Expose a record instance that’s setup outside of using ‘create`/`upsert`.
-
#upsert(label = nil, unique_by: nil, **attributes) ⇒ Object
Upsert a record in the database with the passed ‘attributes`.
Constructor Details
#initialize(loader, type) ⇒ ActiveRecord
Returns a new instance of ActiveRecord.
2 3 4 5 |
# File 'lib/oaken/stored/active_record.rb', line 2 def initialize(loader, type) @loader, @type = loader, type @attributes = loader.defaults_for(*type.column_names) end |
Instance Attribute Details
#type ⇒ Object (readonly)
Returns the value of attribute type.
6 7 8 |
# File 'lib/oaken/stored/active_record.rb', line 6 def type @type end |
Instance Method Details
#attributes_for(**attributes) ⇒ Object
Build attributes used for ‘create`/`upsert`, applying loader and per-type `defaults`.
loader.defaults name: -> { "Global" }, email_address: -> { … }
users.defaults name: -> { Faker::Name.name } # This `name` takes precedence on users.
users.attributes_for(email_address: "[email protected]") # => { name: "Some Faker Name", email_address: "[email protected]" }
38 39 40 |
# File 'lib/oaken/stored/active_record.rb', line 38 def attributes_for(**attributes) @attributes.merge(attributes).transform_values! { _1.respond_to?(:call) ? _1.call : _1 } end |
#create(label = nil, unique_by: nil, **attributes) ⇒ Object
Create a record in the database with the passed ‘attributes`.
11 12 13 14 15 16 17 18 19 20 |
# File 'lib/oaken/stored/active_record.rb', line 11 def create(label = nil, unique_by: nil, **attributes) attributes = attributes_for(**attributes) finders = attributes.slice(*unique_by) record = type.find_by(finders)&.tap { _1.update!(**attributes) } if finders.any? record ||= type.create!(**attributes) _label label, record.id if label record end |
#defaults(**attributes) ⇒ Object
Set defaults for all types:
loader.defaults name: -> { "Global" }, email_address: -> { … }
These defaults are used and evaluated in ‘create`/`upsert`/`attributes_for`, but you can override on a per-type basis:
users.defaults name: -> { Faker::Name.name } # This `name` takes precedence on `users`.
users.create # => Uses the users' default `name` and the loader `email_address`
50 |
# File 'lib/oaken/stored/active_record.rb', line 50 def defaults(**attributes) = @attributes = @attributes.merge(attributes) |
#label(**labels) ⇒ Object
Expose a record instance that’s setup outside of using ‘create`/`upsert`. Like this:
users.label someone: User.create!(name: "Someone")
users.label someone: FactoryBot.create(:user, name: "Someone")
Now ‘users.someone` returns the record instance.
Ruby’s Hash argument forwarding also works:
someone, someone_else = users.create(name: "Someone"), users.create(name: "Someone Else")
users.label someone:, someone_else:
Note: ‘users.method(:someone).source_location` also points back to the file and line of the `label` call.
65 |
# File 'lib/oaken/stored/active_record.rb', line 65 def label(**labels) = labels.each { |label, record| _label label, record.id } |
#upsert(label = nil, unique_by: nil, **attributes) ⇒ Object
Upsert a record in the database with the passed ‘attributes`.
23 24 25 26 27 28 29 30 |
# File 'lib/oaken/stored/active_record.rb', line 23 def upsert(label = nil, unique_by: nil, **attributes) attributes = attributes_for(**attributes) type.new(attributes).validate! record = type.new(id: type.upsert(attributes, unique_by: unique_by, returning: :id).rows.first.first) _label label, record.id if label record end |