Class: ActiveRecordCompose::Model

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Model, Attributes, Inspectable, Persistence, TransactionSupport, Validations
Defined in:
lib/active_record_compose/model.rb

Overview

This is the core class of ActiveRecordCompose.

By defining subclasses of this model, you can use ActiveRecordCompose functionality in your application. It has the basic functionality of ActiveModel::Model and ActiveModel::Attributes, and also provides aggregation of multiple models and atomic updates through transaction control.

Examples:

Example of model registration.

class AccountRegistration < ActiveRecordCompose::Model
  def initialize( = Account.new, attributes = {})
    @account = 
    @profile = @account.build_profile
    models <<  << profile
    super(attributes)
  end

  attribute :register_confirmation, :boolean, default: false
  delegate_attribute :name, :email, to: :account
  delegate_attribute :firstname, :lastname, :age, to: :profile

  validates :register_confirmation, presence: true

  private

  attr_reader :account, :profile
end

Multiple model update once.

registration = AccountRegistration.new
registration.assign_attributes(
  name: "alice-in-wonderland",
  email: "alice@example.com",
  firstname: "Alice",
  lastname: "Smith",
  age: 24,
  register_confirmation: true
)

registration.save!      # Register Account and Profile models at the same time.
Account.count           # => (0 ->) 1
Profile.count           # => (0 ->) 1

Attribute delegation.

 = Account.new
.name = "foo"

registration = AccountRegistration.new()
registration.name         # => "foo" (delegated)
registration.name?        # => true  (delegated attribute method + `?`)

registration.name = "bar" # => updates account.name
.name              # => "bar"
.name?             # => true

registration.attributes   # => { "original_attribute" => "qux", "name" => "bar" }

Aggregate errors on invalid.

registration = AccountRegistration.new

registration.name = "alice-in-wonderland"
registration.firstname = "Alice"
registration.age = 18

registration.valid?
#=> false

# The error contents of the objects stored in models are aggregated.
# For example, direct access to errors in Account#email.
registration.errors[:email].to_a  # Account#email
#=> ["can't be blank"]

# Of course, the validation defined for itself is also working.
registration.errors[:register_confirmation].to_a
#=> ["can't be blank"]

registration.errors.to_a
#=> ["Email can't be blank", "Lastname can't be blank", "Register confirmation can't be blank"]

Instance Method Summary collapse

Methods included from Inspectable

filter_attributes, filter_attributes=, #inspect, #pretty_print

Methods included from Attributes

attribute_names, #attribute_names, #attributes, delegate_attribute

Methods included from TransactionSupport

after_commit, after_rollback, #save, #save!

Methods included from Validations

#save, #save!, #valid?, #validate, #validate!

Methods included from Persistence

#save, #save!, #update, #update!

Methods included from Callbacks

after_create, after_save, after_update, around_create, around_save, around_update, before_create, before_save, before_update

Constructor Details

#initialize(attributes = {}) ⇒ Model

Returns a new instance of Model.



92
93
94
# File 'lib/active_record_compose/model.rb', line 92

def initialize(attributes = {})
  super
end

Instance Method Details

#idObject

Returns the ID value. This value is used when passing it to the :model option of form_with, etc. Normally it returns nil, but it can be overridden to delegate to the containing model.

Examples:

Redefine the id method by delegating to the containing model

class Foo < ActiveRecordCompose::Model
  def initialize(primary_model)
    @primary_model = primary_model
    # ...
  end

  def id
    primary_model.id
  end

  private

  attr_reader :primary_model
end

Returns:

  • (Object)

    ID value



117
# File 'lib/active_record_compose/model.rb', line 117

def id = nil

#modelsActiveRecordCompose::ComposedCollection (private)

Returns a collection of model elements to encapsulate.

Examples:

Adding models

models << inner_model_a << inner_model_b
models.push(inner_model_c)

#push can have :destroy :if options

models.push(profile, destroy: :blank_profile?)
models.push(profile, destroy: -> { blank_profile? })

Returns:



130
# File 'lib/active_record_compose/model.rb', line 130

def models = @__models ||= ActiveRecordCompose::ComposedCollection.new(self)