Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/maximeg/mongoid_max_denormalize
An efficient denormalization extension for Mongoid.
https://github.com/maximeg/mongoid_max_denormalize
Last synced: 6 days ago
JSON representation
An efficient denormalization extension for Mongoid.
- Host: GitHub
- URL: https://github.com/maximeg/mongoid_max_denormalize
- Owner: maximeg
- License: mit
- Created: 2012-06-14T07:28:50.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2013-02-24T16:16:35.000Z (over 11 years ago)
- Last Synced: 2024-10-29T01:19:23.264Z (9 days ago)
- Language: Ruby
- Size: 282 KB
- Stars: 22
- Watchers: 2
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Mongoid::Max::Denormalize
`Mongoid::Max::Denormalize` is a denormalization extension for Mongoid. It was designed to do a minimum number of queries to the database.
* Denormalize fields
* Denormalize methods (only in One to Many situations for now)
* Denormalize `count` in Many to One situations
* Propagate only when needed:
* for fields: when there are actual changes
* for methods: always (we can't know in an inexpensive way what is the old value to figure out if there is a change)
* Take advantage of atomic operations on multiple documents of MongoDB**Versions supported:** Mongoid 3.0 and Mongoid 2.4
[![Continuous Integration status](https://secure.travis-ci.org/maximeg/mongoid_max_denormalize.png)](http://travis-ci.org/maximeg/mongoid_max_denormalize)## Installation
Add the gem to your Gemfile:
gem 'mongoid_max_denormalize'
Or install with RubyGems:
$ gem install mongoid_max_denormalize
## Usage
### Basic usage
Add `include Mongoid::Max::Denormalize` in your model and also:
```ruby
denormalize :relation, :field_1, :field_2 ... :field_n, :options_1 => :value, :options_2 => :value
```### Warming up
If there are existing records prior to the denormalization setup, you have to warm up. See below for each relation type.
Note: you can't warm up from both sides of the relation. Only the most efficient is available.
### One to Many
**Supported fields:** normal Mongoid fields, and methods.
**Supported options:** none.
#### Example:
```ruby
class Post
include Mongoid::Documentfield :title
def slug
title.try(:parameterize)
endhas_many :comments
endclass Comment
include Mongoid::Document
include Mongoid::Max::Denormalizebelongs_to :post
denormalize :post, :title, :slug
end@post = Post.create(:title => "Mush from the Wimp")
@comment = @post.comments.create
@comment.post_title #=> "Mush from the Wimp"
@comment.post_slug #=> "mush-from-the-wimp"@post.update_attributes(:title => "All Must Share The Burden")
@comment.reload # to reload the comment from the DB
@comment.post_title #=> "All Must Share The Burden"
@comment.post_slug #=> "all-must-share-the-burden"
```To warm up the denormalization for an existing collection:
```ruby
Post.denormalize_to_comments!
```**Tips :** In your views, do not use `@comment.post` but `@comment.post_id` or `@comment.post_id?`
to avoid a query that checks/retrieve for the post. We want to avoid it, don't we ?Exemple : Check your logs, you'll see queries for the post :
# app/views/comments/_comment.html.erb
This is better :
# app/views/comments/_comment.html.erb
<% if @comment.post_id? %>
<%= link_to @comment.post_title, post_path(@comment.post_id, :slug => @comment.post_slug) %>
<% end %>
### Many to One
**Supported fields:** only normal Mongoid fields, no methods *(optionnal)*
**Supported options:**
* `:count => true` : to keep a count !
#### Example:
```ruby
class Post
include Mongoid::Document
include Mongoid::Max::Denormalizehas_many :comments
denormalize :comments, :rating, :stuff, :count => true
endclass Comment
include Mongoid::Documentbelongs_to :post
field :rating
field :stuff
end@post = Post.create
@comment = @post.comments.create(:rating => 5, :stuff => "A")
@comment = @post.comments.create(:rating => 3, :stuff => "B")
@post.reload
@post.comments_count #=> 2
@post.comments_rating #=> [5, 3]
@post.comments_stuff #=> ["A", "B"]
```To warm up the denormalization for an existing collection:
```ruby
Post.denormalize_from_comments!
```You can see that each denormalized field in stored in a separate array. This is wanted.
An option `:group` will come to allow the way below (and maybe permit methods denormalization) :```ruby
@post.comments_fields #=> [{:rating => 5, :stuff => "A"}, {:rating => 5, :stuff => "B"}]
```#### Example 2: only count
```ruby
class Post
include Mongoid::Document
include Mongoid::Max::Denormalizehas_many :comments
denormalize :comments, :count => true
endclass Comment
include Mongoid::Documentbelongs_to :post
end@post = Post.create
@comment = @post.comments.create
@comment = @post.comments.create
@post.reload
@post.comments_count #=> 2
```### Many to Many
To come...
## Planned
* Support for Many to Many
* Support for `:group` option in Many to One
* Support for methods denormalization in Many to One (depends on `:group` option)
* Support for `:sum` and `:mean` options in Many to One
* Support for `:touch` option to "touch" an `updated_at` field (for cache purpose)## Contributing
Contributions and bug reports are welcome.
Clone the repository and run `bundle install` to setup the development environment.
Provide a case spec according to your changes/needs, taking example on existing ones (in `spec/cases`).
To run the specs:
bundle exec rspec
## Credits
* Maxime Garcia [emaxime.com](http://emaxime.com) [@maximegarcia](http://twitter.com/maximegarcia)
[License](https://github.com/maximeg/mongoid_max_denormalize/blob/master/LICENSE)
\- [Report a bug](https://github.com/maximeg/mongoid_max_denormalize/issues).
<% if @comment.post %>
<%= link_to @comment.post_title, @comment.post %>
<% end %>