Created
January 16, 2013 19:58
-
-
Save goshacmd/4550323 to your computer and use it in GitHub Desktop.
Mongoid inline relation definitions. Ruby makes it so easy ❤️
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
# Mongoid inline relation definitions. Ruby makes it so easy. | |
# (`data` is effectively just a shortcut for `inline_embed_one(:data)` there.) | |
# | |
# Yes, it would make sense to create separate models, but my case is different. | |
# This application is used to track events of other apps, such as purchase, and | |
# it makes *more* sense to embed all order-related data. Instead of having model | |
# overload for each event being tracked, I just define them inline. | |
class OrderEvent | |
include Analyzing::Event | |
event_for :shop | |
data do | |
field :total_price, type: Float | |
field :currency, type: String | |
field :total_price_usd, type: Float | |
field :name, type: String | |
inline_embed_one :customer do | |
field :first_name, type: String | |
field :last_name, type: String | |
field :email, type: String | |
end | |
inline_embed_many :line_items do | |
field :name, type: String | |
field :title, type: String | |
field :price, type: Float | |
field :quantity, type: Integer | |
field :sku, type: String | |
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 MongoidExt | |
extend ActiveSupport::Concern | |
module ClassMethods | |
# Public: Define embeds_one inline. Class and actual relation will be | |
# created automatically for you. | |
# | |
# rel_name - The Symbol relation name. Class name will be created based | |
# on it. Additionally it will be used to define "embeds_one" | |
# relation. | |
# options - The Hash "embeds_one" options. | |
# block - The block used to define Mongoid Document. | |
# | |
# Examples | |
# | |
# class Some | |
# inline_embed_one :association_name do | |
# # embedded class definition here | |
# end | |
# end | |
def inline_embed_one(rel_name, options = {}, &block) | |
em_class_name = rel_name.to_s.camelize | |
em_class = Class.new | |
const_set(em_class_name, em_class) | |
em_class.tap do |klass| | |
klass.send(:include, Mongoid::Document) | |
klass.send(:include, MongoidExt) | |
klass.class_eval(&block) | |
end | |
embeds_one rel_name, options.merge(class_name: "#{name}::#{em_class_name}", autobuild: true) | |
end | |
# Public: Define embeds_many inline. Class and actual relation will be | |
# created automatically for you. | |
# | |
# rel_name - The Symbol relation name. Class name will be created based | |
# on it. Additionally it will be used to define "embeds_many" | |
# relation. | |
# options - The Hash "embeds_many" options. | |
# block - The block used to define Mongoid Document. | |
# | |
# Examples | |
# | |
# class Some | |
# inline_embed_many :association_name do | |
# # embedded class definition here | |
# end | |
# end | |
def inline_embed_many(rel_name, options = {}, &block) | |
em_class_name = rel_name.to_s.singularize.camelize | |
em_class = Class.new | |
const_set(em_class_name, em_class) | |
em_class.tap do |klass| | |
klass.send(:include, Mongoid::Document) | |
klass.send(:include, MongoidExt) | |
klass.class_eval(&block) | |
end | |
embeds_many rel_name, options.merge(class_name: "#{name}::#{em_class_name}") | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment