neo4j-rails 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +8 -0
- data/History.txt +3 -0
- data/LICENSE.txt +23 -0
- data/README.markdown +76 -0
- data/Rakefile +40 -0
- data/lib/neo4j-rails.rb +2 -0
- data/lib/neo4j-rails/version.rb +3 -0
- data/lib/neo4j/delayed_save.rb +67 -0
- data/lib/neo4j/model.rb +100 -0
- data/lib/neo4j/rails.rb +2 -0
- data/lib/neo4j/railtie.rb +21 -0
- data/lib/neo4j/transaction_management.rb +15 -0
- data/neo4j-rails.gemspec +33 -0
- data/spec/neo4j/model_spec.rb +156 -0
- data/spec/spec_helper.rb +75 -0
- metadata +109 -0
data/Gemfile
ADDED
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#--
|
2
|
+
# The MIT License
|
3
|
+
#
|
4
|
+
# Copyright (c) 2010 Engine Yard, Inc.
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
23
|
+
#++
|
data/README.markdown
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Neo4j-Rails
|
2
|
+
|
3
|
+
This is an experimental library for playing with an
|
4
|
+
ActiveModel-charged version of the [Neo4j.rb][neo4j] Ruby library. The
|
5
|
+
intent is to use it as a full replacement for ActiveRecord inside a
|
6
|
+
Rails 3 application.
|
7
|
+
|
8
|
+
Of course you can use Neo4j.rb as is in a Rails application, but this
|
9
|
+
library uses ActiveModel to make the API and usage even closer to
|
10
|
+
ActiveRecord. One example of this is the way `Model.new` works.
|
11
|
+
|
12
|
+
In Neo4j.rb, `Node.new` requires a transaction and immediately stores
|
13
|
+
the node in the database.In Neo4j-Rails, object initialization matches
|
14
|
+
ActiveRecord-style two-step `Model.new` + `Model#save` creation. This
|
15
|
+
makes it easier to create forms that don't touch the database if
|
16
|
+
validation fails.
|
17
|
+
|
18
|
+
# Usage
|
19
|
+
|
20
|
+
Include the 'neo4j-rails' library in your Gemfile to use in your
|
21
|
+
project.
|
22
|
+
|
23
|
+
gem "neo4j-rails"
|
24
|
+
|
25
|
+
Extend Neo4j::Model to create your model node classes.
|
26
|
+
|
27
|
+
class IceCream < Neo4j::Model
|
28
|
+
property :flavour
|
29
|
+
validates_presence_of :flavour
|
30
|
+
end
|
31
|
+
|
32
|
+
IceCream.new.valid? # => false
|
33
|
+
IceCream.new(:flavour => "vanilla").valid? # => true
|
34
|
+
|
35
|
+
Configure the location of the Neo4j database and Lucene index files on
|
36
|
+
disk. The Lucene search index will normally be created in memory, so
|
37
|
+
set `store_on_file = true` to save it to disk. Usually these settings
|
38
|
+
will go in `config/application.rb` or `config/environments/*.rb`.
|
39
|
+
|
40
|
+
Rails.application.configure do
|
41
|
+
config.neo4j.storage_path = "/var/neo4j"
|
42
|
+
config.lucene.storage_path = "/var/lucene"
|
43
|
+
config.lucene.store_on_file = true
|
44
|
+
end
|
45
|
+
|
46
|
+
# API
|
47
|
+
|
48
|
+
Many of the familiar API methods from ActiveRecord are duplicated in
|
49
|
+
Neo4j::Model. Neo4j::Model includes ActiveModel::Validations,
|
50
|
+
ActiveModel::Conversions, and ActiveModel::Callbacks.
|
51
|
+
|
52
|
+
class Neo4j::Model
|
53
|
+
def valid?; end
|
54
|
+
def save; end
|
55
|
+
def save!; end
|
56
|
+
def update_attributes(attributes); end
|
57
|
+
def update_attributes!(attributes); end
|
58
|
+
def destroy; end
|
59
|
+
def attributes=(attrs); end
|
60
|
+
def reload; end
|
61
|
+
def self.all; end
|
62
|
+
def self.find(*); end
|
63
|
+
def self.create(attributes); end
|
64
|
+
def self.create!(attributes); end
|
65
|
+
end
|
66
|
+
|
67
|
+
# License
|
68
|
+
|
69
|
+
Neo4j-Rails is available under the terms of the MIT license (see
|
70
|
+
LICENSE.txt for details).
|
71
|
+
|
72
|
+
However, Neo4j-Rails also depends on the [Neo4j.rb library][neo4j], and the MIT
|
73
|
+
license does not replace or cover the licensing terms of its own
|
74
|
+
library or its components.
|
75
|
+
|
76
|
+
[neo4j]: http://github.com/andreasronge/neo4j
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
require './lib/neo4j-rails/version'
|
5
|
+
gemspec = Gem::Specification.new do |s|
|
6
|
+
s.name = %q{neo4j-rails}
|
7
|
+
s.version = Neo4jRails::VERSION
|
8
|
+
s.authors = ["Nick Sieger"]
|
9
|
+
s.date = Date.today.to_s
|
10
|
+
s.description = %{Adapts Neo4j for Rails 3 apps using ActiveModel}
|
11
|
+
s.summary = %q{Neo4j adapter for Rails 3}
|
12
|
+
s.email = ["nick@nicksieger.com"]
|
13
|
+
s.files = FileList["lib/**/*", "spec/**/*",
|
14
|
+
*%w(Gemfile neo4j-rails.gemspec History.txt LICENSE.txt Rakefile README.markdown)
|
15
|
+
].select {|f| File.file?(f) }
|
16
|
+
s.homepage = %q{http://jruby.org}
|
17
|
+
s.has_rdoc = false
|
18
|
+
s.add_dependency('rails', ">= 3.0.0.beta2")
|
19
|
+
s.add_dependency('neo4j', ">= 0.4.3")
|
20
|
+
end
|
21
|
+
|
22
|
+
task :gemspec do
|
23
|
+
File.open("neo4j-rails.gemspec", "w") {|f| f << gemspec.to_ruby }
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'rake/gempackagetask'
|
27
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
28
|
+
end
|
29
|
+
|
30
|
+
task :release => :package do
|
31
|
+
if Neo4jRails::VERSION != ENV['VERSION']
|
32
|
+
abort "Versions do not match: #{Neo4jRails::VERSION.inspect} != #{ENV['VERSION'].inspect}"
|
33
|
+
end
|
34
|
+
sh "gem push pkg/neo4j-rails-#{Neo4jRails::VERSION}.gem"
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'spec/rake/spectask'
|
38
|
+
Spec::Rake::SpecTask.new
|
39
|
+
|
40
|
+
task :default => :spec
|
data/lib/neo4j-rails.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Extension to Neo4j::NodeMixin to delay creating/updating properties
|
2
|
+
# until #save is called.
|
3
|
+
module Neo4j::DelayedSave
|
4
|
+
def id
|
5
|
+
persisted? ? neo_id : nil
|
6
|
+
end
|
7
|
+
|
8
|
+
# Override NodeMixin#init_without_node to save the properties for
|
9
|
+
# when #save is called.
|
10
|
+
def init_without_node(props) # :nodoc:
|
11
|
+
raise "Can't use Neo4j::Model with anonymous classes" if self.class.name == ""
|
12
|
+
props[:_classname] = self.class.name
|
13
|
+
@_unsaved_props = props || {}
|
14
|
+
@persisted = false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Ensure nodes loaded from the database are marked as persisted.
|
18
|
+
def init_with_node(node)
|
19
|
+
super
|
20
|
+
@persisted = true
|
21
|
+
@_unsaved_props = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Delegate property access to temporary properties first
|
25
|
+
def [](key)
|
26
|
+
if @_unsaved_props.has_key?(key)
|
27
|
+
@_unsaved_props[key]
|
28
|
+
elsif @_java_node
|
29
|
+
@_java_node[key]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Delegate property write to temporary properties
|
34
|
+
def []=(key, value)
|
35
|
+
@_unsaved_props[key] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def reload(*)
|
39
|
+
@_unsaved_props.clear
|
40
|
+
self
|
41
|
+
end
|
42
|
+
alias_method :reset, :reload
|
43
|
+
|
44
|
+
def save
|
45
|
+
if valid?
|
46
|
+
_run_save_callbacks do
|
47
|
+
if @persisted
|
48
|
+
_run_update_callbacks do
|
49
|
+
@_unsaved_props.each {|k,v| @_java_node[k] = v }
|
50
|
+
@_unsaved_props.clear
|
51
|
+
end
|
52
|
+
else
|
53
|
+
_run_create_callbacks do
|
54
|
+
@_java_node = Neo4j.create_node
|
55
|
+
@_java_node._wrapper = self
|
56
|
+
@_unsaved_props.each {|k,v| @_java_node[k] = v }
|
57
|
+
@_unsaved_props.clear
|
58
|
+
update_index
|
59
|
+
Neo4j.event_handler.node_created(self)
|
60
|
+
@persisted = true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/neo4j/model.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'neo4j'
|
2
|
+
require 'neo4j/extensions/reindexer'
|
3
|
+
require 'active_model'
|
4
|
+
require 'neo4j/delayed_save'
|
5
|
+
|
6
|
+
class Neo4j::Model
|
7
|
+
include Neo4j::NodeMixin
|
8
|
+
include Neo4j::DelayedSave
|
9
|
+
include ActiveModel::Conversion
|
10
|
+
include ActiveModel::Validations
|
11
|
+
extend ActiveModel::Callbacks
|
12
|
+
define_model_callbacks :create, :save, :update, :destroy
|
13
|
+
|
14
|
+
class RecordInvalidError < RuntimeError
|
15
|
+
attr_reader :record
|
16
|
+
def initialize(record)
|
17
|
+
@record = record
|
18
|
+
super(@record.errors.full_messages.join(", "))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def persisted?
|
23
|
+
@persisted
|
24
|
+
end
|
25
|
+
|
26
|
+
def read_attribute_for_validation(key)
|
27
|
+
self[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def attributes=(attrs)
|
31
|
+
attrs.each do |k,v|
|
32
|
+
if respond_to?("#{k}=")
|
33
|
+
send("#{k}=", v)
|
34
|
+
else
|
35
|
+
self[k] = v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_attributes(attributes)
|
41
|
+
self.attributes = attributes
|
42
|
+
save
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_attributes!(attributes)
|
46
|
+
self.attributes = attributes
|
47
|
+
save!
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy
|
51
|
+
_run_destroy_callbacks do
|
52
|
+
del
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def save!
|
57
|
+
unless save
|
58
|
+
raise RecordInvalidError.new(self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.load(*ids)
|
63
|
+
result = ids.map {|id| Neo4j.load_node(id) }
|
64
|
+
if ids.length == 1
|
65
|
+
result.first
|
66
|
+
else
|
67
|
+
result
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.all
|
72
|
+
super.nodes
|
73
|
+
end
|
74
|
+
|
75
|
+
# Handle Model.find(params[:id])
|
76
|
+
def self.find(*args)
|
77
|
+
if args.length == 1 && String === args[0] && args[0].to_i != 0
|
78
|
+
load(*args)
|
79
|
+
else
|
80
|
+
super
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.create(*args)
|
85
|
+
new(*args).tap {|model| model.save }
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.create!(*args)
|
89
|
+
new(*args).tap {|model| model.save! }
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.inherited(subc) # :nodoc:
|
93
|
+
# Make subclasses of Neo4j::Model each have their own root class/indexer
|
94
|
+
subc.instance_eval do
|
95
|
+
def root_class
|
96
|
+
self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/neo4j/rails.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
require 'neo4j/transaction_management'
|
3
|
+
|
4
|
+
module Neo4j
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
config.neo4j = ActiveSupport::OrderedOptions.new
|
7
|
+
config.lucene = ActiveSupport::OrderedOptions.new
|
8
|
+
|
9
|
+
initializer "neo4j.tx" do |app|
|
10
|
+
app.config.middleware.use Neo4j::TransactionManagement
|
11
|
+
end
|
12
|
+
|
13
|
+
# Starting Neo after :load_config_initializers allows apps to
|
14
|
+
# register migrations in config/initializers
|
15
|
+
initializer "neo4j.start", :after => :load_config_initializers do |app|
|
16
|
+
Neo4j::Config.setup.merge!(app.config.neo4j.to_hash)
|
17
|
+
Lucene::Config.setup.merge!(app.config.lucene.to_hash)
|
18
|
+
Neo4j.start
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/neo4j-rails.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{neo4j-rails}
|
5
|
+
s.version = "0.5"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Nick Sieger"]
|
9
|
+
s.date = %q{2010-06-06}
|
10
|
+
s.description = %q{Adapts Neo4j for Rails 3 apps using ActiveModel}
|
11
|
+
s.email = ["nick@nicksieger.com"]
|
12
|
+
s.files = ["lib/neo4j-rails.rb", "lib/neo4j/delayed_save.rb", "lib/neo4j/model.rb", "lib/neo4j/rails.rb", "lib/neo4j/railtie.rb", "lib/neo4j/transaction_management.rb", "lib/neo4j-rails/version.rb", "spec/spec_helper.rb", "spec/neo4j/model_spec.rb", "Gemfile", "neo4j-rails.gemspec", "History.txt", "LICENSE.txt", "Rakefile", "README.markdown"]
|
13
|
+
s.homepage = %q{http://jruby.org}
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
s.rubygems_version = %q{1.3.7}
|
16
|
+
s.summary = %q{Neo4j adapter for Rails 3}
|
17
|
+
|
18
|
+
if s.respond_to? :specification_version then
|
19
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
20
|
+
s.specification_version = 3
|
21
|
+
|
22
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
23
|
+
s.add_runtime_dependency(%q<rails>, [">= 3.0.0.beta2"])
|
24
|
+
s.add_runtime_dependency(%q<neo4j>, [">= 0.4.3"])
|
25
|
+
else
|
26
|
+
s.add_dependency(%q<rails>, [">= 3.0.0.beta2"])
|
27
|
+
s.add_dependency(%q<neo4j>, [">= 0.4.3"])
|
28
|
+
end
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<rails>, [">= 3.0.0.beta2"])
|
31
|
+
s.add_dependency(%q<neo4j>, [">= 0.4.3"])
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'neo4j/model'
|
3
|
+
|
4
|
+
class IceCream < Neo4j::Model
|
5
|
+
property :flavour
|
6
|
+
index :flavour
|
7
|
+
validates_presence_of :flavour
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Neo4j::Model, "new" do
|
11
|
+
before :each do
|
12
|
+
@model = Neo4j::Model.new
|
13
|
+
end
|
14
|
+
subject { @model }
|
15
|
+
|
16
|
+
it { should_not be_persisted }
|
17
|
+
|
18
|
+
it "should allow access to properties before it is saved" do
|
19
|
+
@model["fur"] = "none"
|
20
|
+
@model["fur"].should == "none"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should fail to save new model without a transaction" do
|
24
|
+
lambda { @model.save }.should raise_error
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Neo4j::Model, "load" do
|
29
|
+
before :each do
|
30
|
+
txn do
|
31
|
+
@model = fixture(Neo4j::Model.new)
|
32
|
+
@model.save
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should load a previously stored node" do
|
37
|
+
result = Neo4j::Model.load(@model.id)
|
38
|
+
result.should == @model
|
39
|
+
result.should be_persisted
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Neo4j::Model, "save" do
|
44
|
+
use_transactions
|
45
|
+
before :each do
|
46
|
+
@model = fixture(IceCream.new)
|
47
|
+
@model.flavour = "vanilla"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should store the model in the database" do
|
51
|
+
@model.save
|
52
|
+
@model.should be_persisted
|
53
|
+
IceCream.load(@model.id).should == @model
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not save the model if it is invalid" do
|
57
|
+
@model = IceCream.new
|
58
|
+
@model.save.should_not be_true
|
59
|
+
@model.should_not be_valid
|
60
|
+
@model.should_not be_persisted
|
61
|
+
@model.id.should be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe Neo4j::Model, "find" do
|
66
|
+
before :each do
|
67
|
+
txn do
|
68
|
+
@model = fixture(IceCream.new)
|
69
|
+
@model.flavour = "vanilla"
|
70
|
+
@model.save
|
71
|
+
end
|
72
|
+
end
|
73
|
+
use_transactions
|
74
|
+
|
75
|
+
it "should load all nodes of that type from the database" do
|
76
|
+
IceCream.all.should include(@model)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should find a model by one of its attributes" do
|
80
|
+
IceCream.find(:flavour => "vanilla").to_a.should include(@model)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe Neo4j::Model, "lint" do
|
85
|
+
before :each do
|
86
|
+
@model = Neo4j::Model.new
|
87
|
+
end
|
88
|
+
|
89
|
+
include_tests ActiveModel::Lint::Tests
|
90
|
+
end
|
91
|
+
|
92
|
+
describe Neo4j::Model, "destroy" do
|
93
|
+
insert_dummy_model
|
94
|
+
|
95
|
+
it "should remove the model from the database" do
|
96
|
+
txn { @model.destroy }
|
97
|
+
txn { Neo4j::Model.load(@model.id).should be_nil }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe Neo4j::Model, "create" do
|
102
|
+
use_transactions
|
103
|
+
|
104
|
+
it "should save the model and return it" do
|
105
|
+
model = Neo4j::Model.create
|
106
|
+
model.should be_persisted
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should accept attributes to be set" do
|
110
|
+
model = Neo4j::Model.create :name => "Nick"
|
111
|
+
model[:name].should == "Nick"
|
112
|
+
end
|
113
|
+
|
114
|
+
it "bang version should raise an exception if save returns false" do
|
115
|
+
lambda { IceCream.create! }.should raise_error(Neo4j::Model::RecordInvalidError)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should run before and after create callbacks" do
|
119
|
+
klass = model_subclass do
|
120
|
+
property :created, :type => DateTime
|
121
|
+
before_create :timestamp
|
122
|
+
def timestamp
|
123
|
+
self.created = DateTime.now
|
124
|
+
end
|
125
|
+
after_create :mark_saved
|
126
|
+
attr_reader :saved
|
127
|
+
def mark_saved
|
128
|
+
@saved = true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
klass.marshal?(:created).should be_true
|
132
|
+
model = klass.create!
|
133
|
+
model.created.should_not be_nil
|
134
|
+
model.saved.should_not be_nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe Neo4j::Model, "update_attributes" do
|
139
|
+
insert_dummy_model
|
140
|
+
|
141
|
+
it "should save the attributes" do
|
142
|
+
txn { @model.update_attributes(:a => 1, :b => 2).should be_true }
|
143
|
+
txn { @model[:a].should == 1; @model[:b].should == 2 }
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should not update the model if it is invalid" do
|
147
|
+
klass = model_subclass do
|
148
|
+
property :name
|
149
|
+
validates_presence_of :name
|
150
|
+
end
|
151
|
+
model = nil
|
152
|
+
txn { model = fixture(klass.create!(:name => "vanilla")) }
|
153
|
+
txn { model.update_attributes(:name => nil).should be_false }
|
154
|
+
txn { model.reload.name.should == "vanilla" }
|
155
|
+
end
|
156
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
begin
|
2
|
+
require File.expand_path('../../.bundle/environment', __FILE__)
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler'
|
6
|
+
Bundler.setup
|
7
|
+
end
|
8
|
+
Bundler.require :default, :test
|
9
|
+
|
10
|
+
require 'spec'
|
11
|
+
require 'spec/interop/test'
|
12
|
+
|
13
|
+
# Since we're using spec/interop/test, we might as well add our
|
14
|
+
# helpers to T::U::TC
|
15
|
+
class Test::Unit::TestCase
|
16
|
+
def self.use_transactions
|
17
|
+
before :each do
|
18
|
+
Neo4j::Transaction.new
|
19
|
+
end
|
20
|
+
|
21
|
+
after :each do
|
22
|
+
Neo4j::Transaction.failure
|
23
|
+
Neo4j::Transaction.finish
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def txn(&block)
|
28
|
+
Neo4j::Transaction.run(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
# HAX: including a module of test_ methods doesn't seem to get them
|
32
|
+
# registered, so I'm registering them manually
|
33
|
+
def self.include_tests(mod)
|
34
|
+
include mod
|
35
|
+
mod.instance_methods(false).each do |m|
|
36
|
+
example(m, {}) {__send__ m}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
after :each do
|
41
|
+
txn { fixtures.each { |obj| obj.del rescue nil } }
|
42
|
+
end
|
43
|
+
|
44
|
+
def fixtures
|
45
|
+
@fixtures ||= []
|
46
|
+
end
|
47
|
+
|
48
|
+
def fixture(obj)
|
49
|
+
self.fixtures << obj
|
50
|
+
obj
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.insert_dummy_model
|
54
|
+
before :each do
|
55
|
+
txn do
|
56
|
+
@model = fixture(Neo4j::Model.new)
|
57
|
+
@model.save
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module TempModel
|
63
|
+
@@_counter = 1
|
64
|
+
def self.set(klass)
|
65
|
+
name = "Model_#{@@_counter}"
|
66
|
+
@@_counter += 1
|
67
|
+
const_set(name,klass)
|
68
|
+
klass
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def model_subclass(&block)
|
73
|
+
TempModel.set(Class.new(Neo4j::Model, &block))
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: neo4j-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
- 1
|
9
|
+
version: 0.5.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Nick Sieger
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-06-06 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rails
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 3
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
- beta2
|
33
|
+
version: 3.0.0.beta2
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: neo4j
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 4
|
47
|
+
- 3
|
48
|
+
version: 0.4.3
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
description: Adapts Neo4j for Rails 3 apps using ActiveModel
|
52
|
+
email:
|
53
|
+
- nick@nicksieger.com
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- lib/neo4j-rails.rb
|
62
|
+
- lib/neo4j/delayed_save.rb
|
63
|
+
- lib/neo4j/model.rb
|
64
|
+
- lib/neo4j/rails.rb
|
65
|
+
- lib/neo4j/railtie.rb
|
66
|
+
- lib/neo4j/transaction_management.rb
|
67
|
+
- lib/neo4j-rails/version.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
- spec/neo4j/model_spec.rb
|
70
|
+
- Gemfile
|
71
|
+
- neo4j-rails.gemspec
|
72
|
+
- History.txt
|
73
|
+
- LICENSE.txt
|
74
|
+
- Rakefile
|
75
|
+
- README.markdown
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://jruby.org
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
requirements: []
|
102
|
+
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.3.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Neo4j adapter for Rails 3
|
108
|
+
test_files: []
|
109
|
+
|