ooor 1.9.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -71
- data/Rakefile +5 -0
- data/bin/ooor +1 -0
- data/lib/ooor.rb +87 -129
- data/lib/ooor/associations.rb +64 -0
- data/lib/ooor/base.rb +218 -0
- data/lib/{app/models → ooor}/base64.rb +0 -0
- data/lib/ooor/connection.rb +37 -0
- data/lib/ooor/errors.rb +120 -0
- data/lib/ooor/field_methods.rb +153 -0
- data/lib/{app → ooor}/helpers/core_helpers.rb +2 -2
- data/lib/ooor/locale.rb +13 -0
- data/lib/ooor/mini_active_resource.rb +94 -0
- data/lib/ooor/model_registry.rb +19 -0
- data/lib/ooor/naming.rb +73 -0
- data/lib/ooor/rack.rb +114 -0
- data/lib/ooor/railtie.rb +41 -0
- data/lib/ooor/reflection.rb +537 -0
- data/lib/ooor/reflection_ooor.rb +92 -0
- data/lib/{app/models → ooor}/relation.rb +61 -22
- data/lib/ooor/relation/finder_methods.rb +113 -0
- data/lib/ooor/report.rb +53 -0
- data/lib/{app/models → ooor}/serialization.rb +18 -6
- data/lib/ooor/services.rb +133 -0
- data/lib/ooor/session.rb +120 -0
- data/lib/ooor/session_handler.rb +63 -0
- data/lib/ooor/transport.rb +34 -0
- data/lib/ooor/transport/json_client.rb +53 -0
- data/lib/ooor/transport/xml_rpc_client.rb +15 -0
- data/lib/ooor/type_casting.rb +193 -0
- data/lib/ooor/version.rb +8 -0
- data/spec/helpers/test_helper.rb +11 -0
- data/spec/install_nightly.sh +17 -0
- data/spec/ooor_spec.rb +197 -79
- data/spec/requirements.txt +19 -0
- metadata +58 -20
- data/lib/app/models/client_xmlrpc.rb +0 -34
- data/lib/app/models/open_object_resource.rb +0 -486
- data/lib/app/models/services.rb +0 -47
- data/lib/app/models/type_casting.rb +0 -134
- data/lib/app/models/uml.rb +0 -210
- data/lib/app/ui/action_window.rb +0 -96
- data/lib/app/ui/client_base.rb +0 -36
- data/lib/app/ui/form_model.rb +0 -88
- data/ooor.yml +0 -27
data/README.md
CHANGED
@@ -1,96 +1,48 @@
|
|
1
|
-
|
2
|
-
====
|
3
|
-
|
4
|
-
<table>
|
5
|
-
<tr>
|
6
|
-
<td width="159px"><a href="http://github.com/rvalyi/ooor" title="OOOR - OpenObject On Ruby"><img src="http://akretion.s3.amazonaws.com/assets/ooor_m.jpg" width="159px" height="124px" /></a></td>
|
7
|
-
<td><b>BY</b></td>
|
8
|
-
<td width="320px"><a href="http://www.akretion.com" title="Akretion - open source to spin the world"><img src="http://akretion.s3.amazonaws.com/assets/logo.png" width="320px" height="154px" /></a></td>
|
9
|
-
<td width="285px">
|
10
|
-
OOOR stands for OpenObject On Ruby. OpenObject is the RAD framework behind OpenERP,
|
11
|
-
the ERP that doesn't hurt, just like Rails is "web development that doesn't hurt".
|
12
|
-
So OOOR exposes seamlessly your OpenObject application, to your custom Ruby or Rails application.
|
13
|
-
Needless to say, OOOR doubly doesn't hurt.
|
14
|
-
Furthermore, OOOR only depends on the "activeresource" gem. So it can even be used
|
15
|
-
in any Ruby application without Rails. It's also fully JRuby compatible and hence make the bridge between the Python OpenERP and the Java ecosystem.
|
16
|
-
</td>
|
17
|
-
</tr>
|
18
|
-
</table>
|
19
|
-
|
20
|
-
|
21
|
-
Why?
|
22
|
-
------------
|
23
|
-
|
24
|
-
OpenERP makes it really straightforward to create custom business applications with:
|
1
|
+
[![Build Status](https://secure.travis-ci.org/akretion/ooor.png?branch=master)](http://travis-ci.org/akretion/ooor) [![Code Climate](https://codeclimate.com/github/akretion/ooor.png)](https://codeclimate.com/github/akretion/ooor)
|
25
2
|
|
26
|
-
|
27
|
-
* complex relationnal data model, with automated migration and backoffice interfaces
|
28
|
-
* ACID transactions on PostgreSQL
|
29
|
-
* role based
|
30
|
-
* modular
|
31
|
-
* integrated BPM (Business Process Management)
|
32
|
-
* integrated reporting system, with integrated translations
|
33
|
-
* both native GTK/QT clients and standard web access
|
3
|
+
[![OOOR by Akretion](https://s3.amazonaws.com/akretion/assets/ooor_by_akretion.png)](http://akretion.com)
|
34
4
|
|
35
|
-
In a word OpenERP really shines when it's about quickly creating the backoffice of those enterprise applications.
|
36
|
-
OpenERP is a bit higher level than Rails (for instance it's component oriented while Rails is REST oriented) so if you adhere to the OpenERP conventions,
|
37
|
-
then you are done faster than coding a Rails app (seriously).
|
38
|
-
Adhering means: you stick to OpenObject views, widgets, look and feel, components composition, ORM (kind of ActiveRecord), the Postgres database...
|
39
5
|
|
40
|
-
|
41
|
-
|
42
|
-
Well that's where OOOR comes into action. It allows you to build a Rails application much like you want, where you totally control the end user presentation and interaction.
|
43
|
-
But OOOR makes it straightforward to use a standard OpenERP models as your persistent models.
|
6
|
+
Why use Ooor?
|
7
|
+
-------------
|
44
8
|
|
45
|
-
|
46
|
-
|
47
|
-
|
9
|
+
* Ooor is an **administration Swiss Army knife** in interactive IRB sessions. It lets you connect remotely to any running OpenERP instance without stopping it, without compromising its security. It has tab auto-completion and object introspection features.
|
10
|
+
* Ooor is a **data migration tool** (inside Kettle with the TerminatOOOR JRuby plugin). Your favorite ETL with OpenERP API super-powers!
|
11
|
+
* Ooor is the basis for unleashed **web development**, using any **Rack** framework such as **Sinatra** or **Rails**.
|
48
12
|
|
49
|
-
|
50
|
-
We use RSpec to test OOOR againt OpenERP [here](http://github.com/rvalyi/ooor/blob/master/spec/ooor_spec.rb) and thanks to the initiative of CampToCamp, the OpenERP community tests OpenERP business features extensively
|
51
|
-
using Cucumber in [OEPScenario](http://launchpad.net/oerpscenario).
|
13
|
+
OpenERP is all the rage for ERP back-offices, but sometimes you want **freedom and scalablity** for your web front ends and this is exactly what Ooor offers you. It enables you to just **reuse OpenERP Model layer** (yay! no data duplication!) and let you build the other layers much the way you want, possibly standing on the shoulders of giants like Rails. Ooor even has an optionnal Rack filter that enables you to proxy some OpenERP applications of your choice (say the shopping cart for instance) and share the HTTP session with it. Ooor is also published under the **MIT licence** so it frees you from the OpenERP AGPL license contamination for your web developements.
|
52
14
|
|
53
|
-
An other usage of OOOR, is it ability to bridge the OpenERP Python world and and the Java world thanks to its JRuby compatibility. This is especially useful in to do extensive "Data Integration" with OpenERP and benefit from the
|
54
|
-
most powerful Java based ETL's. The main project here is [TerminatOOOR](http://github.com/rvalyi/terminatooor), a Pentaho ETL Kettle 4 plugin allowing to push/pull data into/from OpenERP with an incomparable flexibility and yet benefit
|
55
|
-
all standard ETL features, including the AgileBI OLAP business intelligence plugin.
|
56
15
|
|
57
|
-
|
16
|
+
Related projects - a full web stack!
|
17
|
+
------------------------------------
|
58
18
|
|
19
|
+
* [Ooorest](http://github.com/akretion/ooorest), Ooor is the **Model** layer of **MVC**. Ooorest is the **Controller** layer, enforcing a clean Railish **REST API** and offering handy **helper** to use OpenERP in your Rails application.
|
20
|
+
* [Aktooor](http://github.com/akretion/aktooor), Aktoor is the missing **View** layer of **MVC**. It's based on [SimpleForm](https://github.com/plataformatec/simple_form), that is a clean minimalist framework that extend Rails form framework over [Twitter Bootstrap](http://getbootstrap.com)
|
21
|
+
* [Erpify](http://github.com/akretion/erpify), Erpify is OpenERP inside the Liquid non evaling language, that is the templating language of Shopify or LocomotiveCMS for instance.
|
22
|
+
* [Locomotive-erpify](http://github.com/akretion/locomtive-erpify), Erpify for LocomotiveCMS, both the engine and the Wagon local editor
|
23
|
+
* [Solarize](http://github.com/akretion/solarize), pulling data from OpenERP relational database may not scale to your need. No problem with Solarize: you can index your OpenERP data with the [Solerp](http://github.com/akretion/solerp) OpenERP module, then search it using SolR API and even load it from SolR without even hitting OpenERP!
|
24
|
+
* [TerminatOOOR](http://github.com/rvalyi/terminatooor), a Pentaho ETL Kettle plugin allowing to push/pull data into/from OpenERP with an incomparable flexibility and yet benefit all standard ETL features, including the AgileBI OLAP business intelligence plugin.
|
59
25
|
|
60
26
|
|
61
27
|
How?
|
62
28
|
------------
|
63
29
|
|
64
|
-
OpenERP is a Python based open source ERP.
|
65
|
-
|
66
|
-
|
67
|
-
OOOR aims at being a very simple piece of code (< 500 lines of code; e.g no bug, [heavility tested](http://github.com/rvalyi/ooor/blob/master/spec/ooor_spec.rb), easy to evolve) adhering to Rails standards.
|
68
|
-
So instead of re-inventing the wheel, OOOR basically just sits on the top of Rails [ActiveResource::Base](http://api.rubyonrails.org/classes/ActiveResource/Base.html), the standard way of remoting you ActiveRecord Rails models with REST.
|
30
|
+
OpenERP is a Python based open source ERP. But every action in OpenERP is actually exposed as a webservice (SOA orientation, close to being RESTful).
|
31
|
+
Ooor doesn't connect to the OpenERP database, instead it uses the OpenERP data access **JSON API** so it fully enforces OpenERP security model and business logic.
|
69
32
|
|
70
|
-
|
71
|
-
So ActiveResource is only a subset of ActiveRecord, sharing the common denominator API (integration is expected to become even more powerful in Rails 3).
|
33
|
+
Ooor is less than 2000 lines of code. It has a test coverage of around 80%. It doesn't embed any business rule, it's just a client to OpenERP. The code of Ooor is modeled after Rails [ActiveModel](http://api.rubyonrails.org/classes/ActiveModel/Model.html), [ActiveResource](https://github.com/rails/activeresource) and [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) layers.
|
72
34
|
|
73
|
-
|
35
|
+
More specifically, an OpenERP Ooor proxy implements the ActiveModel API. Instead of depending on ActiveResource which is actually a bit different (not multi-tenant, little access right management), we copied a tiny subset of it in the mini_active_resource.rb file and OpenERP proxies include this module. Finally Ooor emulates the ActiveRecord API wherever possible delegating its requests to OpenERP using OpenERP domain [S expressions](http://en.wikipedia.org/wiki/S-expression) instead of SQL. The ActiveRecord API emulation is actually pretty good: think **Ooor looks more like ActiveRecord than Mongoid**; it has associations, surface ARel API, Reflection API, can be paginated via Kaminary, can be integrated with SimpleForm or Cocoon seamlessly...
|
74
36
|
|
75
|
-
|
76
|
-
Indeed, when loading the OpenERP models, we load the relational meta-model using OpenERP standard datamodel introspection services.
|
77
|
-
Then we cache that relational model and use it in OpenObjectResource.method_missing to load associations as requested.
|
78
|
-
|
79
|
-
OOOR also extends ActiveResource a bit with special request parameters (like :domain or :context) that will just map smoothly to the OpenERP native API, see API.
|
37
|
+
Ooor features **several session modes**: in the default IRB console usage it uses a global login scheme and generate constants for your OpenERP proxies, such as ProductProduct for the product.product OpenERP object much like Rails ActiveRecord. In web mode instead, you can have several sessions and do session['product.product'] to get a proxy to the Product object matching your current session credentials, chosen database and OpenERP url (yes Ooor is not only multi-database like OpenEP, it's in fact **multi-OpenERP**!)
|
80
38
|
|
81
39
|
|
82
40
|
Installation
|
83
41
|
------------
|
84
42
|
|
85
|
-
You can use OOOR in a standalone (J)Ruby application, or in a Rails application, it only depends on the activeresource gem.
|
86
|
-
For both example we assume that you already started some OpenERP server on localhost, with XML/RPC on port 8069 (default),
|
87
|
-
with a database called 'mybase', with username 'admin' and password 'admin'.
|
88
|
-
|
89
|
-
In all case, you first need to install Ruby, then the rubygems package manager and finally the ooor gem with:
|
90
|
-
|
91
43
|
$ gem install ooor
|
92
|
-
(the ooor gem is hosted [on gemcutter.org here](http://gemcutter.org/gems/ooor), make sure you have it in your gem source lists, a way is to do >gem tumble)
|
93
44
|
|
45
|
+
(Warning Ooor has been ureleased for several months, don't hesitate to run the git version instead)
|
94
46
|
|
95
47
|
Trying it simply
|
96
48
|
------------
|
@@ -130,7 +82,7 @@ Please read details [https://github.com/rvalyi/ooor/wiki/(J)Ruby-on-Rails-applic
|
|
130
82
|
API usage
|
131
83
|
------------
|
132
84
|
|
133
|
-
Note: Ruby
|
85
|
+
Note: Ruby proxy objects are named after OpenERP models in but removing the '.' and using CamelCase.
|
134
86
|
(we remind you that OpenERP tables are also named after OpenERP models but replacing the '.' by '_'.)
|
135
87
|
|
136
88
|
Basic finders:
|
data/Rakefile
ADDED
data/bin/ooor
CHANGED
data/lib/ooor.rb
CHANGED
@@ -1,155 +1,113 @@
|
|
1
1
|
# OOOR: OpenObject On Ruby
|
2
|
-
# Copyright (C) 2009-
|
2
|
+
# Copyright (C) 2009-2013 Akretion LTDA (<http://www.akretion.com>).
|
3
3
|
# Author: Raphaël Valyi
|
4
4
|
# Licensed under the MIT license, see MIT-LICENSE file
|
5
5
|
|
6
|
+
require 'active_support/dependencies/autoload'
|
7
|
+
require 'active_support/concern'
|
8
|
+
require 'active_support/cache'
|
6
9
|
require 'logger'
|
7
|
-
|
8
|
-
require 'app/models/services'
|
9
|
-
require 'app/models/base64'
|
10
|
-
require 'app/ui/client_base'
|
10
|
+
|
11
11
|
|
12
12
|
module Ooor
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
extend ActiveSupport::Autoload
|
14
|
+
autoload :Base
|
15
|
+
autoload :Cache, 'active_support/cache'
|
16
|
+
autoload :Serialization
|
17
|
+
autoload :Relation
|
18
|
+
autoload :TypeCasting
|
19
|
+
autoload :Naming
|
20
|
+
autoload :Associations
|
21
|
+
autoload :FieldMethods
|
22
|
+
autoload :Report
|
23
|
+
autoload :Locale
|
24
|
+
autoload :Transport
|
25
|
+
autoload :Block
|
26
|
+
autoload :MiniActiveResource
|
27
|
+
autoload :SessionHandler
|
28
|
+
autoload :ModelRegistry
|
29
|
+
autoload :UnknownAttributeOrAssociationError, 'ooor/errors'
|
30
|
+
autoload :OpenERPServerError, 'ooor/errors'
|
31
|
+
autoload :HashWithIndifferentAccess, 'active_support/core_ext/hash/indifferent_access'
|
16
32
|
|
17
|
-
|
18
|
-
|
19
|
-
@extensions[model_name] ||= []
|
20
|
-
@extensions[model_name] << block
|
21
|
-
@extensions
|
33
|
+
autoload_under 'relation' do
|
34
|
+
autoload :FinderMethods
|
22
35
|
end
|
23
36
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
rescue SystemCallError
|
42
|
-
puts """failed to load OOOR yaml configuration file.
|
43
|
-
make sure your app has a #{config_file} file correctly set up
|
44
|
-
if not, just copy/paste the default ooor.yml file from the OOOR Gem
|
45
|
-
to #{Rails.root}/config/ooor.yml and customize it properly\n\n"""
|
46
|
-
{}
|
47
|
-
end
|
37
|
+
module OoorBehavior
|
38
|
+
extend ActiveSupport::Concern
|
39
|
+
module ClassMethods
|
40
|
+
|
41
|
+
attr_accessor :default_config, :default_session, :cache_store
|
42
|
+
|
43
|
+
IRREGULAR_CONTEXT_POSITIONS = {
|
44
|
+
import_data: 5,
|
45
|
+
fields_view_get: 2,
|
46
|
+
search: 4,
|
47
|
+
name_search: 3,
|
48
|
+
read_group: 5,
|
49
|
+
fields_get: 1,
|
50
|
+
read: 2,
|
51
|
+
perm_read: 1,
|
52
|
+
check_recursion: 1
|
53
|
+
}
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if
|
53
|
-
|
54
|
-
require 'jooor'
|
55
|
-
@rpc_clients[url] = get_java_rpc_client(url)
|
56
|
-
rescue LoadError
|
57
|
-
puts "WARNING falling back on Ruby xmlrpc/client client (much slower). Install the 'jooor' gem if you want Java speed for the RPC!"
|
58
|
-
@rpc_clients[url] = get_ruby_rpc_client(url)
|
59
|
-
end
|
60
|
-
else
|
61
|
-
@rpc_clients[url] = get_ruby_rpc_client(url)
|
55
|
+
def new(config={})
|
56
|
+
Ooor.default_config = config.merge(generate_constants: true)
|
57
|
+
session = session_handler.retrieve_session(config)
|
58
|
+
if config[:database] && config[:password]
|
59
|
+
session.global_login(config)
|
62
60
|
end
|
61
|
+
Ooor.default_session = session
|
63
62
|
end
|
64
|
-
@rpc_clients[url]
|
65
|
-
end
|
66
63
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
64
|
+
def cache(store=nil)
|
65
|
+
@cache_store ||= ActiveSupport::Cache.lookup_store(store)
|
66
|
+
end
|
71
67
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@base_url = @config[:url] = "#{@config[:url].gsub(/\/$/,'').chomp('/xmlrpc')}/xmlrpc"
|
79
|
-
@loaded_models = []
|
80
|
-
scope = Module.new and Object.const_set(@config[:scope_prefix], scope) if @config[:scope_prefix]
|
81
|
-
global_login(@config[:username] || 'admin', @config[:password] || 'admin', @config[:database], @config[:models]) if @config[:database]
|
82
|
-
end
|
68
|
+
def xtend(model_name, &block)
|
69
|
+
@extensions ||= {}
|
70
|
+
@extensions[model_name] ||= []
|
71
|
+
@extensions[model_name] << block
|
72
|
+
@extensions
|
73
|
+
end
|
83
74
|
|
84
|
-
|
85
|
-
|
86
|
-
|
75
|
+
def extensions
|
76
|
+
@extensions ||= {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def session_handler() @session_handler ||= SessionHandler.new; end
|
80
|
+
def model_registry() @model_registry ||= ModelRegistry.new; end
|
81
|
+
|
82
|
+
def logger
|
83
|
+
@logger ||= Logger.new($stdout)
|
84
|
+
end
|
85
|
+
|
86
|
+
def logger=(logger)
|
87
|
+
@logger = logger
|
88
|
+
end
|
89
|
+
|
90
|
+
def irregular_context_position(method)
|
91
|
+
IRREGULAR_CONTEXT_POSITIONS.merge(default_config[:irregular_context_positions] || {})[method.to_sym]
|
92
|
+
end
|
87
93
|
|
88
|
-
def global_login(user, password, database=@config[:database], model_names=false)
|
89
|
-
@config[:username] = user
|
90
|
-
@config[:password] = password
|
91
|
-
@config[:database] = database
|
92
|
-
@config[:user_id] = login(database, user, password)
|
93
|
-
load_models(model_names, true)
|
94
94
|
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
@ir_model_class = define_openerp_model({'model' => 'ir.model'}, @config[:scope_prefix])
|
100
|
-
model_ids = model_names && @ir_model_class.search([['model', 'in', model_names]]) || @ir_model_class.search() - [1]
|
101
|
-
models = @ir_model_class.read(model_ids, ['model', 'name'])#['name', 'model', 'id', 'info', 'state', 'field_id', 'access_ids'])
|
102
|
-
@global_context.merge!({}).merge!(@config[:global_context] || {}) #TODO ensure it's required
|
103
|
-
models.each {|openerp_model| define_openerp_model(openerp_model, @config[:scope_prefix], nil, nil, nil, nil, reload)}
|
96
|
+
|
97
|
+
def with_ooor_session(config={}, id=nil)
|
98
|
+
yield Ooor.session_handler.retrieve_session(config, id)
|
104
99
|
end
|
105
100
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
if reload || !scope.const_defined?(model_class_name)
|
110
|
-
klass = Class.new(OpenObjectResource)
|
111
|
-
klass.ooor = self
|
112
|
-
klass.site = url || @base_url
|
113
|
-
klass.user = user_id
|
114
|
-
klass.password = pass
|
115
|
-
klass.database = database
|
116
|
-
klass.openerp_model = param['model']
|
117
|
-
klass.openerp_id = url || param['id']
|
118
|
-
klass.info = (param['info'] || '').gsub("'",' ')
|
119
|
-
klass.name = model_class_name
|
120
|
-
klass.description = param['name']
|
121
|
-
klass.state = param['state']
|
122
|
-
#klass.field_ids = param['field_id']
|
123
|
-
#klass.access_ids = param['access_ids']
|
124
|
-
klass.many2one_associations = {}
|
125
|
-
klass.one2many_associations = {}
|
126
|
-
klass.many2many_associations = {}
|
127
|
-
klass.polymorphic_m2o_associations = {}
|
128
|
-
klass.associations_keys = []
|
129
|
-
klass.fields = {}
|
130
|
-
klass.scope_prefix = scope_prefix
|
131
|
-
@logger.debug "registering #{model_class_name} as an ActiveResource proxy for OpenObject #{param['model']} model"
|
132
|
-
scope.const_set(model_class_name, klass)
|
133
|
-
(::Ooor.extensions[param['model']] || []).each {|block| klass.class_eval(&block)}
|
134
|
-
@loaded_models.push(klass)
|
135
|
-
return klass
|
101
|
+
def with_ooor_default_session(config={})
|
102
|
+
if config
|
103
|
+
Ooor.new(config)
|
136
104
|
else
|
137
|
-
|
105
|
+
Ooor.default_session
|
138
106
|
end
|
139
107
|
end
|
140
108
|
end
|
141
|
-
|
142
|
-
|
143
|
-
if Rails.version[0] == "3"[0] #Rails 3 bootstrap
|
144
|
-
class Railtie < Rails::Railtie
|
145
|
-
initializer "ooor.middleware" do |app|
|
146
|
-
Ooor.default_config = Ooor.load_config(false, Rails.env)
|
147
|
-
Ooor.default_ooor = Ooor.new(Ooor.default_config) if Ooor.default_config['bootstrap']
|
148
|
-
end
|
149
|
-
end
|
150
|
-
else #Rails 2.3.x bootstrap
|
151
|
-
Ooor.default_config = Ooor.load_config(false, RAILS_ENV)
|
152
|
-
Ooor.default_ooor = Ooor.new(Ooor.default_config) if Ooor.default_config['bootstrap']
|
153
|
-
end
|
154
|
-
end
|
109
|
+
|
110
|
+
include OoorBehavior
|
155
111
|
end
|
112
|
+
|
113
|
+
require 'ooor/railtie' if defined?(Rails)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Ooor
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
def many2one_id_method(rel, *arguments)
|
5
|
+
if @associations[rel]
|
6
|
+
@associations[rel][0]
|
7
|
+
else
|
8
|
+
obj = method_missing(rel.to_sym, *arguments)
|
9
|
+
obj.is_a?(Base) ? obj.id : obj
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def x_to_many_ids_method(rel, *arguments)
|
14
|
+
if @associations[rel]
|
15
|
+
@associations[rel]
|
16
|
+
else
|
17
|
+
method_missing(rel.to_sym, *arguments)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# fakes associations like much like ActiveRecord according to the cached OpenERP data model
|
22
|
+
def relationnal_result(method_name, *arguments)
|
23
|
+
self.class.reload_fields_definition(false, object_session)
|
24
|
+
if self.class.many2one_associations.has_key?(method_name)
|
25
|
+
if @associations[method_name]
|
26
|
+
rel = self.class.many2one_associations[method_name]['relation']
|
27
|
+
id = @associations[method_name].is_a?(Integer) ? @associations[method_name] : @associations[method_name][0]
|
28
|
+
load_association(rel, id, nil, *arguments)
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
elsif self.class.one2many_associations.has_key?(method_name)
|
33
|
+
rel = self.class.one2many_associations[method_name]['relation']
|
34
|
+
load_association(rel, @associations[method_name], [], *arguments)
|
35
|
+
elsif self.class.many2many_associations.has_key?(method_name)
|
36
|
+
rel = self.class.many2many_associations[method_name]['relation']
|
37
|
+
load_association(rel, @associations[method_name], [], *arguments)
|
38
|
+
elsif self.class.polymorphic_m2o_associations.has_key?(method_name)
|
39
|
+
values = @associations[method_name].split(',')
|
40
|
+
load_association(values[0], values[1].to_i, nil, *arguments)
|
41
|
+
else
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_association(model_key, ids, substitute=nil, *arguments)
|
47
|
+
options = arguments.extract_options!
|
48
|
+
related_class = self.class.const_get(model_key)
|
49
|
+
fields = options[:fields] || options[:only] || nil
|
50
|
+
context = options[:context] || object_session
|
51
|
+
(related_class.send(:find, ids, fields: fields, context: context) || substitute).tap do |r|
|
52
|
+
#TODO the following is a hack to minimally mimic the CollectionProxy of Rails 3.1+; this should probably be re-implemented
|
53
|
+
def r.association=(association)
|
54
|
+
@association = association
|
55
|
+
end
|
56
|
+
r.association = related_class
|
57
|
+
def r.build(attrs={})
|
58
|
+
@association.new(attrs)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|