Class: ROM::Changeset::Associated

Inherits:
Object
  • Object
show all
Extended by:
Initializer
Defined in:
changeset/lib/rom/changeset/associated.rb

Overview

Associated changesets automatically set up FKs

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#associationsArray (readonly)

Returns List of association identifiers from relation schema.

Returns:

  • (Array)

    List of association identifiers from relation schema



19
# File 'changeset/lib/rom/changeset/associated.rb', line 19

option :associations

#leftChangeset::Create (readonly)

Returns Child changeset.

Returns:



15
# File 'changeset/lib/rom/changeset/associated.rb', line 15

param :left

Class Method Details

.infer_assoc_name(other) ⇒ 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.

Infer association name from an object with a schema

This expects other to be an object with a schema that includes a primary key attribute with :source meta information. This makes it work with both structs and relations

See Also:



30
31
32
33
34
35
36
37
38
39
40
# File 'changeset/lib/rom/changeset/associated.rb', line 30

def self.infer_assoc_name(other)
  schema = other.class.schema
  attrs = schema.is_a?(Hash) ? schema.values : schema
  pk = attrs.detect { |attr| attr.meta[:primary_key] }

  if pk
    pk.meta[:source]
  else
    raise ArgumentError, "can't infer association name for #{other}"
  end
end

Instance Method Details

#associate(other, name = Associated.infer_assoc_name(other)) ⇒ Associated

Associate with other changesets

Returns:

See Also:

  • Changeset#associate


65
66
67
# File 'changeset/lib/rom/changeset/associated.rb', line 65

def associate(other, name = Associated.infer_assoc_name(other))
  self.class.new(left, associations: associations.merge(name => other))
end

#commandROM::Command::Composite

Create a composed command

This works only with parent => child(ren) changeset hierarchy

Examples:

using existing parent data

user_changeset = users.changeset(name: 'Jane')
task_changeset = tasks.changeset(title: 'Task One')

user = users.create(user_changeset)
task = tasks.create(task_changeset.associate(user, :user))

saving both parent and child in one go

user_changeset = users.changeset(name: 'Jane')
task_changeset = tasks.changeset(title: 'Task One')

task = tasks.create(task_changeset.associate(user, :user))

Returns:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'changeset/lib/rom/changeset/associated.rb', line 89

def command
  associations.reduce(left.command.curry(left)) do |a, (assoc, other)|
    case other
    when Changeset
      a >> other.command.with_association(assoc).curry(other)
    when Associated
      a >> other.command.with_association(assoc)
    when Array
      raise NotImplementedError, 'Changeset::Associate does not support arrays yet'
    else
      a.with_association(assoc, parent: other)
    end
  end
end

#commitArray<Hash>, Hash

Commit changeset's composite command

Examples:

task_changeset = tasks.
  changeset(title: 'Task One').
  associate(user, :user).
  commit
# {:id => 1, :user_id => 1, title: 'Task One'}

Returns:

  • (Array<Hash>, Hash)


54
55
56
# File 'changeset/lib/rom/changeset/associated.rb', line 54

def commit
  command.call
end

#relationObject

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.



105
106
107
# File 'changeset/lib/rom/changeset/associated.rb', line 105

def relation
  left.relation
end