couchrest model supports custom view definitions
This commit is contained in:
parent
4a1de8c1ba
commit
6a86a00d21
|
@ -45,7 +45,7 @@ module CouchRest
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def create
|
def create
|
||||||
set_uniq_id if respond_to?(:set_uniq_id) # hack
|
set_unique_id if respond_to?(:set_unique_id) # hack
|
||||||
save_doc
|
save_doc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -116,8 +116,8 @@ module CouchRest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def uniq_id method
|
def unique_id method
|
||||||
define_method :set_uniq_id do
|
define_method :set_unique_id do
|
||||||
doc['_id'] ||= self.send(method)
|
doc['_id'] ||= self.send(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -126,25 +126,33 @@ module CouchRest
|
||||||
|
|
||||||
module MagicViews
|
module MagicViews
|
||||||
def view_by *keys
|
def view_by *keys
|
||||||
|
opts = keys.pop if keys.last.is_a?(Hash)
|
||||||
type = self.to_s
|
type = self.to_s
|
||||||
doc_keys = keys.collect{|k|"doc['#{k}']"}
|
|
||||||
key_protection = doc_keys.join(' && ')
|
|
||||||
key_emit = doc_keys.length == 1 ? "#{doc_keys.first}" : "[#{doc_keys.join(', ')}]"
|
|
||||||
map_function = <<-JAVASCRIPT
|
|
||||||
function(doc) {
|
|
||||||
if (doc.type == '#{type}' && #{key_protection}) {
|
|
||||||
emit(#{key_emit}, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JAVASCRIPT
|
|
||||||
|
|
||||||
method_name = "by_#{keys.join('_and_')}"
|
method_name = "by_#{keys.join('_and_')}"
|
||||||
|
|
||||||
@@design_doc ||= default_design_doc
|
@@design_doc ||= default_design_doc
|
||||||
@@design_doc['views'][method_name] = {
|
|
||||||
'map' => map_function
|
if opts && opts[:map]
|
||||||
}
|
view = {}
|
||||||
|
view['map'] = opts[:map]
|
||||||
|
view['reduce'] = opts[:reduce] if opts[:reduce]
|
||||||
|
@@design_doc['views'][method_name] = view
|
||||||
|
else
|
||||||
|
doc_keys = keys.collect{|k|"doc['#{k}']"}
|
||||||
|
key_protection = doc_keys.join(' && ')
|
||||||
|
key_emit = doc_keys.length == 1 ? "#{doc_keys.first}" : "[#{doc_keys.join(', ')}]"
|
||||||
|
map_function = <<-JAVASCRIPT
|
||||||
|
function(doc) {
|
||||||
|
if (doc.type == '#{type}' && #{key_protection}) {
|
||||||
|
emit(#{key_emit}, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JAVASCRIPT
|
||||||
|
@@design_doc['views'][method_name] = {
|
||||||
|
'map' => map_function
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
@@design_doc_fresh = false
|
@@design_doc_fresh = false
|
||||||
|
|
||||||
self.meta_class.instance_eval do
|
self.meta_class.instance_eval do
|
||||||
|
|
|
@ -7,22 +7,35 @@ end
|
||||||
class Article
|
class Article
|
||||||
include CouchRest::Model
|
include CouchRest::Model
|
||||||
use_database CouchRest.database!('http://localhost:5984/couchrest-model-test')
|
use_database CouchRest.database!('http://localhost:5984/couchrest-model-test')
|
||||||
uniq_id :slug
|
unique_id :slug
|
||||||
|
|
||||||
key_accessor :title
|
|
||||||
key_reader :slug, :created_at, :updated_at
|
|
||||||
before(:create, :generate_slug_from_title)
|
|
||||||
|
|
||||||
timestamps!
|
|
||||||
|
|
||||||
def generate_slug_from_title
|
|
||||||
doc['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'')
|
|
||||||
end
|
|
||||||
|
|
||||||
key_writer :date
|
|
||||||
|
|
||||||
view_by :date
|
view_by :date
|
||||||
view_by :user_id, :date
|
view_by :user_id, :date
|
||||||
|
|
||||||
|
view_by :tags,
|
||||||
|
:map =>
|
||||||
|
"function(doc) {
|
||||||
|
if (doc.type == 'Article' && doc.tags) {
|
||||||
|
doc.tags.forEach(function(tag){
|
||||||
|
emit(tag, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}",
|
||||||
|
:reduce =>
|
||||||
|
"function(keys, values, rereduce) {
|
||||||
|
return sum(values);
|
||||||
|
}"
|
||||||
|
|
||||||
|
key_writer :date
|
||||||
|
key_reader :slug, :created_at, :updated_at
|
||||||
|
key_accessor :title
|
||||||
|
|
||||||
|
timestamps!
|
||||||
|
|
||||||
|
before(:create, :generate_slug_from_title)
|
||||||
|
def generate_slug_from_title
|
||||||
|
doc['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe CouchRest::Model do
|
describe CouchRest::Model do
|
||||||
|
@ -130,7 +143,7 @@ describe CouchRest::Model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "saving a model with a uniq_id configured" do
|
describe "saving a model with a unique_id configured" do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@art = Article.new
|
@art = Article.new
|
||||||
@old = Article.database.get('this-is-the-title') rescue nil
|
@old = Article.database.get('this-is-the-title') rescue nil
|
||||||
|
@ -245,4 +258,21 @@ describe CouchRest::Model do
|
||||||
articles[0].title.should == "even more interesting"
|
articles[0].title.should == "even more interesting"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "with a custom view" do
|
||||||
|
before(:all) do
|
||||||
|
@titles = ["very uniq one", "even less interesting", "some fun", "really junk", "crazy bob"]
|
||||||
|
@tags = ["cool", "lame"]
|
||||||
|
@titles.each_with_index do |title,i|
|
||||||
|
u = i % 2
|
||||||
|
a = Article.new(:title => title, :tags => [@tags[u]])
|
||||||
|
a.save
|
||||||
|
puts a.inspect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
it "should be available raw" do
|
||||||
|
view = Article.by_tags :raw => true, :group => true
|
||||||
|
view.should == 'x'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue