ooor 1.9.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/README.md +23 -71
  2. data/Rakefile +5 -0
  3. data/bin/ooor +1 -0
  4. data/lib/ooor.rb +87 -129
  5. data/lib/ooor/associations.rb +64 -0
  6. data/lib/ooor/base.rb +218 -0
  7. data/lib/{app/models → ooor}/base64.rb +0 -0
  8. data/lib/ooor/connection.rb +37 -0
  9. data/lib/ooor/errors.rb +120 -0
  10. data/lib/ooor/field_methods.rb +153 -0
  11. data/lib/{app → ooor}/helpers/core_helpers.rb +2 -2
  12. data/lib/ooor/locale.rb +13 -0
  13. data/lib/ooor/mini_active_resource.rb +94 -0
  14. data/lib/ooor/model_registry.rb +19 -0
  15. data/lib/ooor/naming.rb +73 -0
  16. data/lib/ooor/rack.rb +114 -0
  17. data/lib/ooor/railtie.rb +41 -0
  18. data/lib/ooor/reflection.rb +537 -0
  19. data/lib/ooor/reflection_ooor.rb +92 -0
  20. data/lib/{app/models → ooor}/relation.rb +61 -22
  21. data/lib/ooor/relation/finder_methods.rb +113 -0
  22. data/lib/ooor/report.rb +53 -0
  23. data/lib/{app/models → ooor}/serialization.rb +18 -6
  24. data/lib/ooor/services.rb +133 -0
  25. data/lib/ooor/session.rb +120 -0
  26. data/lib/ooor/session_handler.rb +63 -0
  27. data/lib/ooor/transport.rb +34 -0
  28. data/lib/ooor/transport/json_client.rb +53 -0
  29. data/lib/ooor/transport/xml_rpc_client.rb +15 -0
  30. data/lib/ooor/type_casting.rb +193 -0
  31. data/lib/ooor/version.rb +8 -0
  32. data/spec/helpers/test_helper.rb +11 -0
  33. data/spec/install_nightly.sh +17 -0
  34. data/spec/ooor_spec.rb +197 -79
  35. data/spec/requirements.txt +19 -0
  36. metadata +58 -20
  37. data/lib/app/models/client_xmlrpc.rb +0 -34
  38. data/lib/app/models/open_object_resource.rb +0 -486
  39. data/lib/app/models/services.rb +0 -47
  40. data/lib/app/models/type_casting.rb +0 -134
  41. data/lib/app/models/uml.rb +0 -210
  42. data/lib/app/ui/action_window.rb +0 -96
  43. data/lib/app/ui/client_base.rb +0 -36
  44. data/lib/app/ui/form_model.rb +0 -88
  45. data/ooor.yml +0 -27
data/README.md CHANGED
@@ -1,96 +1,48 @@
1
- OOOR - OpenObject On Ruby:
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
- * standard ERP business modules (more than 500 modules)
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
- But sometimes you can't afford that. Typicall examples are B2C end users applications like e-commerce shops.
41
- So what happens if you don't adhere to the OpenERP framework?
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
- An other reason why you might want to use OOOR is because you would like to code essentially a Rails or say web application
46
- (because you know it better, because the framework is cleaner or because you will reuse something, possibly Java libraries though JRuby)
47
- but you still want to benefit from OpenERP features. Notice that despite its name OOOR doens't hold a dependency upon Rails anymore.
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
- Yet an other typicall use case would be to test your OpenERP application/module using Rails best of bread BDD Ruby frameworks such as RSpec or Cucumber.
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
- Finally you might also want to use OOOR simply to expose your OpenERP through REST to other consumer applications using [the OOOREST project](http://github.com/rvalyi/ooorest).
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. Every action in OpenERP is actually invokable as a webservice (SOA orientation, close to being RESTful).
65
- OOOR just takes advantage of it.
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
- Remember, ActiveResource is actually simpler than [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html). It's aimed at remoting ANY object model, not necessarily ActiveRecord models.
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
- OOOR implements ActiveResource public API almost fully. It means that you can remotely work on any OpenERP model using [the standard ActiveResource API](http://api.rubyonrails.org/classes/ActiveResource/Base.html).
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
- But, OOOR goes actually a bit further: it does implements model associations (one2many, many2many, many2one, single table inheritance, polymorphic associations...).
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 proxies objects are named after OpenERP models in but removing the '.' and using CamelCase.
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
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :default => :spec
data/bin/ooor CHANGED
@@ -4,6 +4,7 @@ puts "*** OOOR - OpenObject on Ruby! Published under the MIT license by Akretion
4
4
 
5
5
  require 'irb'
6
6
  require 'rubygems'
7
+ require 'logger'
7
8
  require 'ooor'
8
9
  require 'irb/completion'
9
10
 
data/lib/ooor.rb CHANGED
@@ -1,155 +1,113 @@
1
1
  # OOOR: OpenObject On Ruby
2
- # Copyright (C) 2009-2012 Akretion LTDA (<http://www.akretion.com>).
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
- require 'app/models/open_object_resource'
8
- require 'app/models/services'
9
- require 'app/models/base64'
10
- require 'app/ui/client_base'
10
+
11
11
 
12
12
  module Ooor
13
- def self.new(*args)
14
- Ooor.send :new, *args
15
- end
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
- def self.xtend(model_name, &block)
18
- @extensions ||= {}
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
- def self.extensions
25
- @extensions
26
- end
27
-
28
- class Ooor
29
- include DbService
30
- include CommonService
31
- include ReportService
32
- include ClientBase
33
-
34
- cattr_accessor :default_ooor, :default_config
35
- attr_accessor :logger, :config, :loaded_models, :base_url, :global_context, :ir_model_class
36
-
37
- #load the custom configuration
38
- def self.load_config(config_file=nil, env=nil)
39
- config_file ||= defined?(Rails.root) && "#{Rails.root}/config/ooor.yml" || 'ooor.yml'
40
- @config = YAML.load_file(config_file)[env || 'development']
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
- def get_rpc_client(url)
50
- @rpc_clients ||= {}
51
- unless @rpc_clients[url]
52
- if defined?(Java) && @config[:rpc_client] != 'ruby'
53
- begin
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
- def get_ruby_rpc_client(url)
68
- require 'app/models/client_xmlrpc'
69
- XMLClient.new2(self, url, nil, @config[:rpc_timeout] || 900)
70
- end
64
+ def cache(store=nil)
65
+ @cache_store ||= ActiveSupport::Cache.lookup_store(store)
66
+ end
71
67
 
72
- def initialize(config, env=false)
73
- @config = config.is_a?(String) ? Ooor.load_config(config, env) : config
74
- @config.symbolize_keys!
75
- @logger = ((defined?(Rails) && $0 != 'irb' && Rails.logger || @config[:force_rails_logger]) ? Rails.logger : Logger.new($stdout))
76
- @logger.level = @config[:log_level] if @config[:log_level]
77
- OpenObjectResource.logger = @logger
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
- def const_get(model_key)
85
- @ir_model_class.const_get(model_key)
86
- end
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
- def load_models(model_names=false, reload=@config[:reload])
97
- @global_context = @config[:global_context] || {}
98
- ([File.dirname(__FILE__) + '/app/helpers/*'] + (@config[:helper_paths] || [])).each {|dir| Dir[dir].each { |file| require file }}
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 define_openerp_model(param, scope_prefix=nil, url=nil, database=nil, user_id=nil, pass=nil, reload=false)
107
- model_class_name = OpenObjectResource.class_name_from_model_key(param['model'])
108
- scope = scope_prefix ? Object.const_get(scope_prefix) : Object
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
- return scope.const_get(model_class_name)
105
+ Ooor.default_session
138
106
  end
139
107
  end
140
108
  end
141
-
142
- if defined?(Rails) #Optional autoload in Rails:
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