Last active
May 24, 2020 14:39
-
-
Save leifcr/1ddc118e47a13c9a7ee3073504192332 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MyProject | |
module Mongoid | |
module Document | |
extend ActiveSupport::Concern | |
included do | |
include ::Mongoid::Document | |
include ::Mongoid::Timestamps | |
include ::Mongoid::DotNotation | |
include ::Mongoid::SearchForObject | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MyProject | |
module Mongoid | |
module EmbeddedDocument | |
extend ActiveSupport::Concern | |
included do | |
include ::Mongoid::Document | |
include ::Mongoid::RootFromEmbedded | |
include ::Mongoid::DotNotation | |
include ::Mongoid::SearchForObject | |
include ::Mongoid::EmbeddedDocumentPath | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Mongoid | |
module EmbeddedDocumentPath | |
extend ActiveSupport::Concern | |
def embedded_document_path | |
edp_get_parent_document(self) | |
end | |
private | |
def edp_get_parent_document(element) | |
retval = Array.new | |
new_els = Array.new | |
p = nil | |
element.reflect_on_all_associations(:embedded_in).each do |r| | |
p = element.send(r.name.to_s) | |
unless p.nil? | |
retval.unshift({klass: p.class.name, id: p.id}) | |
new_els = edp_get_parent_document(p) | |
if new_els.length > 0 | |
new_els.reverse_each do |ne| | |
retval.unshift(ne) | |
end | |
end | |
end | |
end | |
retval | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Mongoid | |
# | |
# Module DotNotation provides Embedded notation for Mongoid Documents | |
# | |
# Add to your mongoid document: | |
# include Mongoid::EmbeddedNotation | |
# | |
# @author Leif Ringstad <[email protected]> | |
# | |
module DotNotation | |
extend ActiveSupport::Concern | |
# | |
# Get dot notification for the current mongoid document. (embedded or not) | |
# | |
# Example | |
# farm_document | |
# has_many fields | |
# field_document | |
# has_many cows | |
# | |
# Calling on a cow will return "fields.cows" | |
# Calling on a field will return "fields" | |
# Calling on a farm will return "" | |
# | |
# @return [String] The dot notation for a given embedded document | |
# | |
def dot_notation | |
dn = dot_notation_for_element_nested(self) | |
if dn.nil? | |
return "" | |
else | |
dn[0] = '' | |
end | |
dn | |
end | |
private | |
# | |
# Get dot notification for nested elements (nesting updwards) | |
# | |
# @param [Mongoid::Document] el A valid Mongoid:Document | |
# | |
# @return [String] The dot notation for a given element | |
# | |
def dot_notation_for_element_nested(el) | |
# Get non-nil_embedded_relation | |
p = get_embedded_relation(el) | |
# puts p.inspect | |
if p.nil? | |
return nil | |
else | |
"#{dot_notation_for_element_nested(p[0])}.#{p[1].inverse_of}" | |
end | |
end | |
# | |
# Get the embedded relation of an object/element | |
# | |
# @param [Mongoid::Document] el A valid Mongoid:Document | |
# | |
# @returns Array [p, r] where p is the parent element for the embedded element, and | |
# r is the inverse reflection name | |
def get_embedded_relation(el) | |
el.reflect_on_all_associations(:embedded_in).each do |r| | |
# puts r.inspect | |
p = el.send(r.name.to_s) | |
return [p, r] unless p.nil? | |
end | |
nil | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Mongoid | |
# Add to your mongoid document: | |
# include Mongoid::RootFromEmbedded | |
# @author Leif Ringstad <[email protected]> | |
module RootFromEmbedded | |
extend ActiveSupport::Concern | |
def root_from_embedded | |
recurse_up_to_highest_element(self) | |
end | |
# | |
# Recurse up to the highest element (root document) | |
# | |
# | |
def recurse_up_to_highest_element(el) | |
p = nil | |
retval = nil | |
el.reflect_on_all_associations(:embedded_in).each do |r| | |
p = el.send(r.name.to_s) | |
unless p.nil? | |
retval = recurse_up_to_highest_element(p) | |
return p if retval.nil? | |
end | |
end | |
retval | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Mongoid | |
# Add to your mongoid document: | |
# include Mongoid::SearchForObject | |
# @author Leif Ringstad <[email protected]> | |
module SearchForObject | |
extend ActiveSupport::Concern | |
# | |
# Search for a object given the dot notation, value and field | |
# | |
# @param [String] dn The dot notation to search for | |
# @param [Array, BigDecimal, Boolean, Date, DateTime, Float, Hash, Integer, Moped::BSON::ObjectId, Moped::BSON::Binary, Range, Regexp, String, Symbol, Time, TimeWithZone] _value The value on the field to search for in any valid Mongoid type. | |
# @param [Symbol] _field The field to search for the value. Default :id | |
# | |
# @return [Array] An array of embedded Mongoid documents | |
# | |
def search_for_object( dn, _value, _field = :id ) | |
return search_value_on_self(_value, _field) if dn.empty? | |
dns = dn.split(".") | |
work_dn = dns.shift | |
remaining_dn = dns.join(".") | |
retval = Array.new | |
if remaining_dn.length == 0 | |
r = search_for_elements_in_array(work_dn, _value, _field) | |
retval.concat(r) unless r.nil? | |
else | |
self.send(work_dn).each do |a| | |
r = a.search_for_object(remaining_dn, _value, _field) | |
retval.concat(r) unless r.nil? | |
end | |
end | |
retval | |
end | |
private | |
# | |
# Find all elements within the array that matches value on a field | |
# | |
# @param [String] dn A dot notation with only one part. Should be a string that the object responds to has_one or has_many | |
# @param [Array, BigDecimal, Boolean, Date, DateTime, Float, Hash, Integer, Moped::BSON::ObjectId, Moped::BSON::Binary, Range, Regexp, String, Symbol, Time, TimeWithZone] _value The value on the field to search for in any valid Mongoid type. | |
# @param [Symbol] _field The field to search for the value. Default :id | |
# | |
# @return [<type>] <description> | |
# | |
def search_for_elements_in_array(dn, _value, _field = :id) | |
return nil unless self.respond_to?(dn) | |
self.send(dn).find_all {|e| e.send(_field) == _value} | |
end | |
# | |
# Search for value on self | |
# | |
# @param [Array, BigDecimal, Boolean, Date, DateTime, Float, Hash, Integer, Moped::BSON::ObjectId, Moped::BSON::Binary, Range, Regexp, String, Symbol, Time, TimeWithZone] _value The value on the field to search for in any valid Mongoid type. | |
# @param [Symbol] _field The field to search for the value. Default :id | |
# | |
# @return [self] <description> | |
# | |
def search_value_on_self(_value, _field) | |
return [self] if (self.send(_field) == _value) | |
nil | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment