Class: AIXM::Concerns::Association::Array

Inherits:
Array
  • Object
show all
Defined in:
lib/aixm/concerns/association.rb

Instance Method Summary collapse

Instance Method Details

#duplicatesArray<Array<AIXM::Feature>>

Find equal or identical duplicates on a has_many association.

Examples:

class Blog
  include AIXM::Concerns::Association
  has_many :posts
end
class Post
  include AIXM::Concerns::Association
  belongs_to :blog
end
blog, post = Blog.new, Post.new
duplicate_post = post.dup
blog.add_posts([post, duplicate_post])
blog.posts.duplicates   # => [[post, duplicate_post]]

Returns:



372
373
374
375
376
# File 'lib/aixm/concerns/association.rb', line 372

def duplicates
  AIXM::Concerns::Memoize.method :to_uid do
    group_by { _1.to_uid.to_s }.select { |_, a| a.count > 1 }.map(&:last)
  end
end

#find(object) ⇒ AIXM::Concerns::Association::Array

Find equal objects on a has_many association.

This may seem redundant at first, but keep in mind that two instances of AIXM::CLASSES which implement ‘#to_uid` are considered equal if they are instances of the same class and both their UIDs as calculated by `#to_uid` are equal. Attributes which are not part of the `#to_uid` calculation are irrelevant!

Examples:

class Blog
  include AIXM::Concerns::Association
  has_many :items, accept: %i(post picture)
end
class Post
  include AIXM::Concerns::Association
  belongs_to :blog, as: :item
  attr_accessor :title
end
blog, post = Blog.new, Post.new
blog.add_item(post)
blog.items.find(post) == [post]   # => true

Parameters:

  • object (Object)

    instance of class listed in AIXM::CLASSES

Returns:



346
347
348
349
350
351
352
353
# File 'lib/aixm/concerns/association.rb', line 346

def find(object)
  klass = object.__class__
  self.class.new(
    select do |element|
      element.kind_of?(klass) && element == object
    end
  )
end

#find_by(klass, attributes = {}) ⇒ AIXM::Concerns::Association::Array

Find objects of the given class and optionally with the given attribute values on a has_many association.

The class can either be declared by passing the class itself or by passing a shortcut symbol as listed in AIXM::CLASSES.

Examples:

class Blog
  include AIXM::Concerns::Association
  has_many :items, accept: %i(post picture)
end
class Post
  include AIXM::Concerns::Association
  belongs_to :blog, as: :item
  attr_accessor :title
end
class Picture
  include AIXM::Concerns::Association
  belongs_to :blog, as: :item
end
blog, post, picture = Blog.new, Post.new, Picture.new
post.title = "title"
blog.add_item(post)
blog.add_item(picture)
blog.items.find_by(:post) == [post]                    # => true
blog.items.find_by(Post) == [post]                     # => true
blog.items.find_by(:post, title: "title") == [post]    # => true
blog.items.find_by(Object) == [post, picture]          # => true

Parameters:

  • klass (Class, Symbol)

    class (e.g. AIXM::Feature::Airport, AIXM::Feature::NavigationalAid::VOR) or shortcut symbol (e.g. :airport or :vor) as listed in AIXM::CLASSES

  • attributes (Hash) (defaults to: {})

    search attributes by their values

Returns:



309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/aixm/concerns/association.rb', line 309

def find_by(klass, attributes={})
  if klass.is_a? Symbol
    klass = AIXM::CLASSES[klass]&.to_class || fail(ArgumentError, "unknown class shortcut `#{klass}'")
  end
  self.class.new(
    select do |element|
      if element.kind_of? klass
        attributes.all? { |a, v| element.send(a) == v }
      end
    end
  )
end