Main goal is to implement Mongoids embedded document functionality in ActiveRecord.
Hash representation of class defined by specified method (default to_h) is saved in json/hstore column.
Adds functionality of embeds_one to ActiveRecord.
Adds functionality of embedded_in to any class initialized with Hash.
Add this line to your application's Gemfile:
gem 'embedson'
And then execute:
$ bundle
Or install it yourself as:
$ gem install embedson
Example with Searchlight is described in blogpost "Persistent queries in Ruby on Rails with PostgreSQL".
Example with Virtus:
#create_tests.rb - migrationclassCreateTests < ActiveRecord::Migrationdefchangecreate_table:testsdo |t|
t.json:dataendendendclassTest < ActiveRecord::Baseembeds_one:virt,class_name: Virt,column_name: :data,inverse_of: :parent,hash_method: :to_h# default optionendclassVirtincludeVirtus.modelextendEmbedson::Modelattribute:name,Stringattribute:address,Hashembedded_in:parent,class_name: Test,inverse_of: :virtendvirt=Virt.new(name: 'Sample',address: {street: 'Kind',number: '33'})virt.attributes# => {:name=>"Sample", :address=>{:street=>"Kind", :number=>"33"}}test=Test.create!test.attributes# => {"id"=>1, "data"=>nil}test.virt=virttest.savetest.attributes# => {"id"=>1, "data"=>{"name"=>"Sample", "address"=>{"street"=>"Kind", "number"=>"33"}}test.reload.virt.attributes# => {:name=>"Sample", :address=>{:street=>"Kind", :number=>"33"}}test.virt == virt# => truetest.virt.parent == test# => trueYou don't have to use all options to define embeds_one and embedded_in. Just name it with downcased related class name.
#create_tests.rb - migrationclassCreateTests < ActiveRecord::Migrationdefchangecreate_table:testsdo |t|
t.json:virtendendendclassTest < ActiveRecord::Baseembeds_one:virtendclassVirtincludeVirtus.modelextendEmbedson::Modelattribute:name,Stringattribute:address,Hashembedded_in:testend####save Assigns
to_hresult to parent and saves it withsave.####save! Assigns
to_hresult to parent and saves it withsave!.####destroy Assigns
nilto parent and saves it withsave!####embedson_model_changed! This gem does not provide dirty tracking of embedded model. To register change in parent model use this method in your setter.
defyour_variable=(arg)@your_variable=argembedson_model_changed!end- Placing
initializemethod afterembedded_inand usingEmb.new(parent: parent)
These examples will work:
classEmbextendEmbedson::Modeldefinitialize(attributes={})# do your work hereendembedded_in:parentendclassEmbextendEmbedson::Modelembedded_in:parentdefinitialize(attributes={})self.parent=attributes[:parent]# do your work hereendendThis will not work!
classEmbextendEmbedson::Modelembedded_in:parentdefinitialize(attributes={})# if you forget about assigning parent# do your work hereendend- Fork it ( https://github.com/[my-github-username]/embedson/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Copyright (c) 2014 Szymon Frącczak. See LICENSE.txt for further details.