ginjo-rfm 3.0.11 → 3.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- M2MxNTI1ZTEyNTc4NjNkYzQ3OTFlNDNlZTVjODFkN2FlNTBiZWUyNw==
5
- data.tar.gz: !binary |-
6
- OGRkNjViNjkxNjQ5NWMzNWI3OGI3MzE4ZjQ2Zjk4MTYwZDU2N2ZmYw==
2
+ SHA1:
3
+ metadata.gz: 9764299badd35b9f4b648765216cc32493d00a0b
4
+ data.tar.gz: ba30aa950a0e9ff80832e605efbcb70da4575286
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MjM5ZGE5ODFjNmY0NDdhNzYxMDNhOTBjY2VlMDdkMTZhMGFkMDJiMWU2ZTVl
10
- OWQzNmRiMDM5MjMzY2RhZjI2MTVkZWNiMTlkNjIyZWMzNTVjZmY5Y2QxODMx
11
- NWRhZjI0OTQyYzhhODI5MzMzNmY3MjIyODI4NmU1NzM2ZjI3ODI=
12
- data.tar.gz: !binary |-
13
- MGEyMzYxYmM2MjYyN2MyMjdmNzMxZmQzZDEzMDNiNjRhNzhiNTM0NjE0ZDMz
14
- YjMyNDFkMTBhMTVmNWVhM2U4ZmIzMWZmZDZhODFjYjA3ZjVhMTYzMWJiNjlm
15
- NTFhN2M3NjAwZjI4NGJmMjc4ZGZhNmUzNDQyOTViNjZiZmZkYTA=
6
+ metadata.gz: fceed96b77df4acb9d368ae7f406cce69f3236009fc8ccbe58d6fe9ce1b52b6a4534935827604dcb45a0fe9e1e77952e5162d363f4178127a0167f7150dfdd2d
7
+ data.tar.gz: 1d0dcc307977a810fa9f11e381ebe0981c74c9916f25697e437bf85dceaee6a5e3ffee8f54d5c7de9484d497bbae28e5d2aef63cf8318066116fe7a839331c80
@@ -1,11 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## Ginjo-Rfm 3.0.12
4
+
5
+ * Make decimal separator configurable, as FM-Server uses local number settings in result set.
6
+ Use configuration option `:decimal_separator`.
7
+
8
+ * Fix broken spec for Ox sax parser.
9
+
10
+ * Change dependency constraint for rspec to >= v2.
11
+
12
+
3
13
  ## Ginjo-Rfm 3.0.11
4
14
 
5
15
  * Scoping fixes, changes, additions:
6
16
 
7
17
  Now takes proc or array of hashes or hash.
8
-
18
+
9
19
  Scope_args for scope proc now defaults to model instance.
10
20
 
11
21
  Now handles omits - puts them at end of request array.
@@ -13,7 +23,7 @@
13
23
  * Support for rom-fmp 0.0.4 - query chaining with compound fm queries.
14
24
 
15
25
  * Basic support for portal field writes.
16
-
26
+
17
27
  record['my_relationship::my_field.0'] = 'Adds a new portal record with data for my_field, if auto-create enabled'
18
28
  record.update_attributes! 'my_relationship::my_field.3' => 'Updates my_field in 3rd portal record, if exists'
19
29
 
@@ -21,6 +31,7 @@
21
31
 
22
32
  * Fix CompoundQuery to handle nil values in query params.
23
33
 
34
+
24
35
  ## Ginjo-Rfm 3.0.10
25
36
 
26
37
  * Fixed bug where missing metadata would cause errors when creating/editing records.
@@ -29,7 +40,7 @@
29
40
 
30
41
  scope = {:person_id => current_user.person_id}
31
42
  Order.find([{:status => ['open', 'processing']}, {:omit => true, :item_count => "<1"}], :scope => scope)
32
-
43
+
33
44
  class Orders < Rfm::Base
34
45
  SCOPE = Proc.new { {:expired => "=" } }
35
46
  end
@@ -56,20 +67,20 @@
56
67
 
57
68
  * Implemented proxy option for database connections thru a proxy server.
58
69
 
59
- config :proxy=>['my.proxy.com', 8888]
60
-
70
+ config :proxy=>['my.proxy.com', 8888]
71
+
61
72
  * Implemented erb parsing of config.yml
62
-
73
+
63
74
  * Disabled ```:grammar => :auto``` option. The current xml parser cannot yet use the FMPXMLRESULT grammar for general queries.
64
75
 
65
76
 
66
77
  ## Ginjo-Rfm 3.0.7
67
78
 
68
79
  * Changed record creation so that generic records created from non-modelized layouts will be instances of Rfm::Record, instead of instances of a transient model class based on the layout. Transient model classes will foul up serialization and any number of other things. Records created from a user-defined model class will continue to be instances of the model class.
69
-
80
+
70
81
  my_layout.find(12345).class == Rfm::Record
71
82
  MyModel.find(12345).class == MyModel
72
-
83
+
73
84
 
74
85
  ## Ginjo-Rfm 3.0.6
75
86
 
@@ -181,9 +192,9 @@
181
192
 
182
193
  * Added grammar translation layer between xml parser and Rfm, allowing all supported xml grammars to be used with Rfm.
183
194
  This will also streamline changes/additions to Filemaker's xml grammar(s).
184
-
195
+
185
196
  * Fixed case statement for ruby 1.9
186
-
197
+
187
198
  * Configuration ```:use``` option now works for all Rfm objects that respond to ```config```.
188
199
 
189
200
  ## Ginjo-Rfm 2.0.2
@@ -233,11 +244,11 @@
233
244
  ## Ginjo-Rfm 1.4.2
234
245
 
235
246
  * Re-implemented:
236
-
247
+
237
248
  Layout#field\_controls
238
249
 
239
250
  Layout#value\_lists
240
-
251
+
241
252
  * Enhanced:
242
253
 
243
254
  ValueListItem handles both display & data items now.
@@ -245,7 +256,7 @@
245
256
  Timeout feature from timting (github/timting/rfm).
246
257
 
247
258
  Added specs for Record#save.
248
-
259
+
249
260
  * Fixed:
250
261
 
251
262
  [Bug] Getting & setting fields with symbol-based keys was producing error.
@@ -259,23 +270,23 @@
259
270
  server.db.all
260
271
  db.layout.all
261
272
  db.script.all
262
-
273
+
263
274
  Note: the "#all" method returns object names (as keys) only. The receiver of the method maintains the full object collection.
264
275
 
265
276
  Example:
266
-
267
- server.db.all #=> ['dbname1', 'dbname2', ...]
268
- server.db #=> a DbFactory object (descendant of Hash), containing 0 or more Database objects
277
+
278
+ server.db.all #=> ['dbname1', 'dbname2', ...]
279
+ server.db #=> a DbFactory object (descendant of Hash), containing 0 or more Database objects
269
280
 
270
281
  ## Lardawge-Rfm 1.4.2 (unreleased)
271
-
282
+
272
283
  * Made nil default on fields with no value.
273
-
284
+
274
285
  Example:
275
286
 
276
287
  Old: record.john #=> ""
277
288
  New: record.john #=> nil
278
-
289
+
279
290
  ## Lardawge-Rfm 1.4.1.2
280
291
 
281
292
  * [Bug] Pointing out why testing is soooooo important when refactoring... Found a bug in getter/setter method in Rfm::Record (yes, added spec for it).
@@ -295,13 +306,13 @@
295
306
  * Added an option to load portal records which defaults to false. This significantly speeds up load time when portals are present on the layout.
296
307
 
297
308
  Example:
298
-
309
+
299
310
  result = fm_server('layout').find({:username => "==#{username}"}, {:include_portals => true})
300
311
  # => This will fetch all records with portal records attached.
301
-
312
+
302
313
  result.first.portals
303
314
  # => would return an empty hash by default.
304
-
315
+
305
316
  * Internal file restructuring. Some classes have changed but it should be nothing a developer would use API wise. Please let me know if it is.
306
317
 
307
318
  * Removed Layout#value\_lists && Layout#field\_controls. Will put back in if the demand is high. Needs a major refactor and different placement if it goes back in. Was broken so it didn't seem to be used by many devs.
data/README.md CHANGED
@@ -1,26 +1,24 @@
1
1
  <!--
2
- See YARD documentation - https://github.com/lsegal/yard/wiki/GettingStarted
3
-
4
- Yard is not the same as markdown - Yard is for ruby and can use any markup language,
5
- whereas Markdown is just another markup language.
6
-
7
- Rubydoc.info uses yard and can use markdown and other markup languages.
8
- To update ginjo-rfm's yard documentation from github's master branch,
9
- first find 'rfm' on rubydoc.info, then in list-view click the update button
10
- on the right of the screen.
11
- To preview this file in yard, run 'rake yard'
12
-
13
- Github uses markdown or rdoc (maybe others?).
14
- To preview this file in plain markdown, edit in TextMate and
15
- choose Bundles/Markdown/Preview menu option.
2
+ See YARD documentation - https://github.com/lsegal/yard/wiki/GettingStarted
3
+
4
+ Yard is not the same as markdown - Yard is for ruby and can use any markup language,
5
+ whereas Markdown is just another markup language.
6
+
7
+ Rubydoc.info uses yard and can use markdown and other markup languages.
8
+ To update ginjo-rfm's yard documentation from github's master branch,
9
+ first find 'rfm' on rubydoc.info, then in list-view click the update button
10
+ on the right of the screen.
11
+ To preview this file in yard, run 'rake yard'
12
+
13
+ Github uses markdown or rdoc (maybe others?).
14
+ To preview this file in plain markdown, edit in TextMate and
15
+ choose Bundles/Markdown/Preview menu option.
16
16
  -->
17
17
 
18
18
  # ginjo-rfm
19
19
 
20
20
  Rfm is a Ruby-Filemaker adapter, a gem that provides an interface between Filemaker Server and Ruby. Query your Filemaker database, browse result records as persistent objects, and create/update/delete records with a syntax similar to ActiveRecord. Ginjo-rfm picks up from the lardawge-rfm gem and continues to refine code and fix bugs. Version 3 removes the dependency on ActiveSupport and is now a completely independent Gem, able to run most of its core features without requiring any other supporting Gems. ActiveModel features can be activated by adding activemodel to your Gemfile (or requiring activemodel manually).
21
21
 
22
- Ginjo-rfm version 3 has been tested successfully on Ruby 1.8.7 thru 2.1.3.
23
-
24
22
 
25
23
  ## Documentation & Links
26
24
 
@@ -72,22 +70,22 @@ The first step in getting connected to your Filemaker databases with Rfm (assumi
72
70
 
73
71
  config/rfm.yml
74
72
 
75
- :host: my.host.com
76
- :account_name: myname
77
- :password: somepass
78
- :database: MyFmDb
79
-
73
+ :host: my.host.com
74
+ :account_name: myname
75
+ :password: somepass
76
+ :database: MyFmDb
77
+
80
78
  app/models/order\_item.rb
81
79
 
82
- class OrderItem < Rfm::Base
83
- config :layout => 'order_item_layout'
84
- end
85
-
80
+ class OrderItem < Rfm::Base
81
+ config :layout => 'order_item_layout'
82
+ end
83
+
86
84
  app/controllers/order\_item\_controller.rb
87
85
 
88
- def show
89
- @record = OrderItem.find params[:id]
90
- end
86
+ def show
87
+ @record = OrderItem.find params[:id]
88
+ end
91
89
 
92
90
 
93
91
  ### Configuration
@@ -96,42 +94,42 @@ In previous versions of Rfm, you may have stored your configuration settings in
96
94
 
97
95
  rfm.yml
98
96
 
99
- :ssl: true
100
- :timeout: 10
101
- :port: 443
102
- :host: my.host.com
103
- :account_name: myname
104
- :password: somepass
105
- :database: MyFmDb
97
+ :ssl: true
98
+ :timeout: 10
99
+ :port: 443
100
+ :host: my.host.com
101
+ :account_name: myname
102
+ :password: somepass
103
+ :database: MyFmDb
106
104
 
107
105
  Or put your configuration settings in a hash called RFM_CONFIG. Rfm will pick those up just as with the yaml file.
108
106
 
109
- RFM_CONFIG = {
110
- :host => 'my.host.com',
111
- :database => 'MyFmDb',
112
- :account_name => 'myname',
113
- :password => 'somepass',
114
- :ssl => true,
115
- :port => 443,
116
- :timeout => 10
117
- }
107
+ RFM_CONFIG = {
108
+ :host => 'my.host.com',
109
+ :database => 'MyFmDb',
110
+ :account_name => 'myname',
111
+ :password => 'somepass',
112
+ :ssl => true,
113
+ :port => 443,
114
+ :timeout => 10
115
+ }
118
116
 
119
117
  You can use configuration subgroups to separate global settings from environment-specific settings.
120
118
 
121
- :ssl: true
122
- :root_cert: false
123
- :timeout: 10
124
- :port: 443
125
- :development:
126
- :host: dev.mydomain.com
127
- :account_name: admin
128
- :password: pass
129
- :database: DevFmDb
130
- :production:
131
- :host: live.mydomain.com
132
- :account_name: admin
133
- :password: pass
134
- :database: LiveFmDb
119
+ :ssl: true
120
+ :root_cert: false
121
+ :timeout: 10
122
+ :port: 443
123
+ :development:
124
+ :host: dev.mydomain.com
125
+ :account_name: admin
126
+ :password: pass
127
+ :database: DevFmDb
128
+ :production:
129
+ :host: live.mydomain.com
130
+ :account_name: admin
131
+ :password: pass
132
+ :database: LiveFmDb
135
133
 
136
134
  Then in your environment files (or wherever you put environment-specific configuration in your Ruby project),
137
135
  specifiy which subgroup to use.
@@ -140,27 +138,27 @@ specifiy which subgroup to use.
140
138
 
141
139
  You can use configuration subgroups to contain any arbitrary groups of settings.
142
140
 
143
- :ssl: true
144
- :root_cert: false
145
- :timeout: 10
146
- :port: 443
147
- :customer1:
148
- :host: customer1.com
149
- :account_name: cust1
150
- :password: pass
151
- :database: custOneFmDb
152
- :customer2:
153
- :host: customer2.com
154
- :account_name: cust2
155
- :password: pass
156
- :database: custTwoFmDb
141
+ :ssl: true
142
+ :root_cert: false
143
+ :timeout: 10
144
+ :port: 443
145
+ :customer1:
146
+ :host: customer1.com
147
+ :account_name: cust1
148
+ :password: pass
149
+ :database: custOneFmDb
150
+ :customer2:
151
+ :host: customer2.com
152
+ :account_name: cust2
153
+ :password: pass
154
+ :database: custTwoFmDb
157
155
 
158
156
  Use the configuration setting method `config` to set configuration for specific objects, like Rfm models. When you pass a `:use => :subgroup` to the `config` method, you're saying use that subgroup of settings (on top of any existing upstream configuration).
159
157
 
160
- class MyModel < Rfm::Base
161
- config :use => :customer1, :layout => 'some_layout'
162
- end
163
-
158
+ class MyModel < Rfm::Base
159
+ config :use => :customer1, :layout => 'some_layout'
160
+ end
161
+
164
162
  The current hierarchy of configurable objects in Rfm, starting at the top, is:
165
163
 
166
164
  * rfm.yml # file of settings in yaml format
@@ -172,132 +170,134 @@ The current hierarchy of configurable objects in Rfm, starting at the top, is:
172
170
 
173
171
  You can also include or extend the Rfm::Config module in any object in your project to gain Rfm configuration abilities for that object.
174
172
 
175
- module MyModule
176
- include Rfm::Config
177
- config :host => 'myhost.com', :database => 'mydb', :account_name => 'name', :password => 'pass'
178
- # inherits settings from Rfm::Config by default
179
- end
173
+ module MyModule
174
+ include Rfm::Config
175
+ config :host => 'myhost.com', :database => 'mydb', :account_name => 'name', :password => 'pass'
176
+ # inherits settings from Rfm::Config by default
177
+ end
180
178
 
181
- class Person < Rfm::Base
182
- config :parent => MyModule, :layout => 'some_layout'
183
- # using :parent to set where this object inherits config settings from
184
- end
179
+ class Person < Rfm::Base
180
+ config :parent => MyModule, :layout => 'some_layout'
181
+ # using :parent to set where this object inherits config settings from
182
+ end
185
183
 
186
184
  Use `get_config` to view the compiled configuration settings for any object. Configuration compilation will start at the top (rfm.yml), then work down the hierarchy of objects to wherever you call the `get_config` method, merging in all global settings along the way. Subgroupings of settings will also be merged, if they are specified in a subgroup filter. A subgroup filter occurs any time you put `:use => :subgroup` in your configuration setting. You can have multiple subgroup filters, and when configuration compilation occurs, all subgroup filters are stacked up into an array and processed in order (as if you typed `:use=>[:subgroup1, :subgroup2, subgroup3, ...]` which is also allowed). `get_config` returns a compiled configuration hash, leaving all configuration settings in all modules and classes un-touched.
187
185
 
188
- Person.get_config
189
-
190
- # => {:ssl => true, :timeout => 10, :root_cert => false, :port => 443,
191
- :host => 'myhost', :database => 'mydb', :layout => 'some_layout',
192
- :account_name => 'name', :password => 'pass'
193
- }
194
-
186
+ Person.get_config
187
+
188
+ # => {:ssl => true, :timeout => 10, :root_cert => false, :port => 443,
189
+ :host => 'myhost', :database => 'mydb', :layout => 'some_layout',
190
+ :account_name => 'name', :password => 'pass'
191
+ }
192
+
195
193
  #### Configuration Options
196
194
 
197
195
  Following are all of the recognized configuration options, including defaults if applicable.
198
196
  See `Rfm::Config::CONFIG_KEYS` for a list of currently allowed configuration options.
199
197
 
200
- :host => 'localhost'
201
- :port
202
- :ssl => true
203
- :root_cert => true
204
- :root_cert_name => ''
205
- :root_cert_path => '/'
206
- :account_name => ''
207
- :password => ''
208
- :proxy => false # Pass an array of Net::HTTP::Proxy options (p_addr, p_port = nil, p_user = nil, p_pass = nil).
209
- :log_actions => false
210
- :log_responses => false
211
- :log_parser => false
212
- :warn_on_redirect => true
213
- :raise_on_401 => false
214
- :timeout => 60
215
-
216
- :use # Use configuration subgroups, or filter configuration subgoups.
217
- :layout # Specify the name of the layout to use.
218
- :parent => 'Rfm::Config' # The parent configuration object of the current configuration object, as string.
219
- :file_name => 'rfm.yml # Name of configuration file to load yaml from.
220
- :file_path => ['', 'config/'] # Array of additional file paths to look for configuration file.
221
- :parser # Prefferred XML parser. Can be :libxml, :nokogiri, :ox, :rexml.
222
- # You must also require the parsing gem or specify it in your gemfile,
223
- # if not using the built-in Ruby XML parser REXML.
224
- # You only need to use this option if you have multiple
225
- # parsing gems loaded and want to use a specfic one.
226
- # Otherwise, Rfm will use the best parser it can find amongst your currently loaded parsing gems.
227
- :ignore_bad_data => nil # Instruct Rfm to ignore data mismatch errors when loading a resultset.
228
-
198
+ :host => 'localhost'
199
+ :port
200
+ :ssl => true
201
+ :root_cert => true
202
+ :root_cert_name => ''
203
+ :root_cert_path => '/'
204
+ :account_name => ''
205
+ :password => ''
206
+ :proxy => false # Pass an array of Net::HTTP::Proxy options (p_addr, p_port = nil, p_user = nil, p_pass = nil).
207
+ :log_actions => false
208
+ :log_responses => false
209
+ :log_parser => false
210
+ :warn_on_redirect => true
211
+ :raise_on_401 => false
212
+ :timeout => 60
213
+
214
+ :use # Use configuration subgroups, or filter configuration subgoups.
215
+ :layout # Specify the name of the layout to use.
216
+ :parent => 'Rfm::Config' # The parent configuration object of the current configuration object, as string.
217
+ :file_name => 'rfm.yml # Name of configuration file to load yaml from.
218
+ :file_path => ['', 'config/'] # Array of additional file paths to look for configuration file.
219
+ :parser # Prefferred XML parser. Can be :libxml, :nokogiri, :ox, :rexml.
220
+ # You must also require the parsing gem or specify it in your gemfile,
221
+ # if not using the built-in Ruby XML parser REXML.
222
+ # You only need to use this option if you have multiple
223
+ # parsing gems loaded and want to use a specfic one.
224
+ # Otherwise, Rfm will use the best parser it can find amongst your currently loaded parsing gems.
225
+ :ignore_bad_data => nil # Instruct Rfm to ignore data mismatch errors when loading a resultset.
226
+ :decimal_separator => '.' # FileMaker uses local number format of the server. It stores input as text.
227
+ # So on european servers a number value of '1.200,50' is considered valid and interpreted as 1200.5
228
+ # To support this, :decimal_separator can be configured and any other characters than digits and the separator are ignored
229
229
 
230
230
  ### Using Models
231
231
 
232
232
  Rfm models provide easy access, modeling, and persistence of your Filemaker data. A ginjo-rfm model is basically an alias to a specific layout in your Filemaker database and provides all of the query options found in a classic rfm layout object. The model and/or the layout object is where you do most of your work with rfm. For more details about what methods and options are available to a model or layout object, see the documentation for the {Rfm::Layout} and {Rfm::Base} classes.
233
233
 
234
- class User < Rfm::Base
235
- config :layout => 'my_user_layout'
236
- attr_accessor :password
237
- end
238
-
239
- @user = User.new(:login => 'bill', :password => 'xxxxxxxx', :email => 'my@email.com')
240
- @user.encrypt_password
241
- @user.save!
242
-
243
- @user.record_id
244
- # => '12345'
245
-
246
- @user.field_names
247
- # => ['login', 'encryptedPassword', 'email', 'groups', 'lastLogin' ]
248
-
249
- User.total_count
250
- # => 35467
251
-
252
- @user = User.find 12345
253
- @user.update_attributes(:login => 'william', :email => 'myother@email.com')
254
- @user.save!
255
-
234
+ class User < Rfm::Base
235
+ config :layout => 'my_user_layout'
236
+ attr_accessor :password
237
+ end
238
+
239
+ @user = User.new(:login => 'bill', :password => 'xxxxxxxx', :email => 'my@email.com')
240
+ @user.encrypt_password
241
+ @user.save!
242
+
243
+ @user.record_id
244
+ # => '12345'
245
+
246
+ @user.field_names
247
+ # => ['login', 'encryptedPassword', 'email', 'groups', 'lastLogin' ]
248
+
249
+ User.total_count
250
+ # => 35467
251
+
252
+ @user = User.find 12345
253
+ @user.update_attributes(:login => 'william', :email => 'myother@email.com')
254
+ @user.save!
255
+
256
256
  If using Rails, put your model code in files within your models/ directory.
257
257
 
258
258
  app/models/user.rb
259
259
 
260
- class User < Rfm::Base
261
- config :layout => 'user_layout'
262
- end
260
+ class User < Rfm::Base
261
+ config :layout => 'user_layout'
262
+ end
263
263
 
264
264
  If you prefer, you can create models on-the-fly from any layout.
265
265
 
266
- my_rfm_layout_object.modelize
267
-
268
- # => MyLayoutName (subclassed from Rfm::Base, represented by your layout's name)
266
+ my_rfm_layout_object.modelize
267
+
268
+ # => MyLayoutName (subclassed from Rfm::Base, represented by your layout's name)
269
269
 
270
270
  Or create models for an entire database, all at once.
271
271
 
272
- Rfm.modelize /_xml/i, 'my_database', :my_config_group
273
-
274
- # => [MyLayoutXml, AnotherLayoutXml, ThirdLayoutXml, AndSoOnXml, ...]
275
- # The regex in the first parameter is optional and filters the layout names in the specified database.
276
- # Omit the regex parameter to modelize all possible layouts in the specified database (careful with this one!).
272
+ Rfm.modelize /_xml/i, 'my_database', :my_config_group
273
+
274
+ # => [MyLayoutXml, AnotherLayoutXml, ThirdLayoutXml, AndSoOnXml, ...]
275
+ # The regex in the first parameter is optional and filters the layout names in the specified database.
276
+ # Omit the regex parameter to modelize all possible layouts in the specified database (careful with this one!).
277
277
 
278
278
  With ActiveModel loaded, you get callbacks, validations, errors, serialization, and a handful of other features extracted from Rails ActiveRecord. Not all ActiveModel features are supported (yet) in ginjo-rfm, but adapters can be hand-rolled in the meantime.
279
279
 
280
280
  In your Gemfile
281
281
 
282
- gem 'activemodel'
283
-
282
+ gem 'activemodel'
283
+
284
284
  Or without Bundler
285
285
 
286
- require 'active_model'
287
-
286
+ require 'active_model'
287
+
288
288
  Then use ActiveModel features in your Rfm models
289
289
 
290
- class MyModel < Rfm::Base
291
- before_create :encrypt_password
292
- after_validate "puts 'yay!'"
293
- validates :email, :presence => true
294
- end
295
-
296
- @my_model = MyModel.new
297
- @my_model.valid?
298
- @my_model.save!
299
- @my_model.errors
300
-
290
+ class MyModel < Rfm::Base
291
+ before_create :encrypt_password
292
+ after_validate "puts 'yay!'"
293
+ validates :email, :presence => true
294
+ end
295
+
296
+ @my_model = MyModel.new
297
+ @my_model.valid?
298
+ @my_model.save!
299
+ @my_model.errors
300
+
301
301
  To learn more about ActiveModel, see the ActiveModel or RubyOnRails documentation:
302
302
 
303
303
  * <http://rubydoc.info/gems/activemodel/frames>
@@ -310,8 +310,8 @@ Once you have an Rfm model or layout, you can use any of the standard Rfm comman
310
310
 
311
311
  (From Rfm v2 onward) When using Models to retrieve records using the `any` method or the `find(record_id)` method, the return values will be single Rfm::Record objects. This differs from the original Rfm behavior of these methods when accessed directly from the the Rfm::Layout instance, where the return value is always a Rfm::Resultset.
312
312
 
313
- MyModel.find(record_id) == my_layout.find(record_id)[0]
314
- MyModel.any == my_layout.any[0]
313
+ MyModel.find(record_id) == my_layout.find(record_id)[0]
314
+ MyModel.any == my_layout.any[0]
315
315
 
316
316
 
317
317
  ### Getting Rfm Server, Database, and Layout Objects Manually
@@ -320,36 +320,36 @@ Well... not entirely manually. To get server, db, and layout objects as in previ
320
320
 
321
321
  Create a layout object using default configuration settings.
322
322
 
323
- my_layout = Rfm.layout 'layout_name'
324
-
323
+ my_layout = Rfm.layout 'layout_name'
324
+
325
325
  Create a layout object using a subgroup of configuration settings.
326
326
 
327
- my_layout = Rfm.layout :subgroup_name
328
-
327
+ my_layout = Rfm.layout :subgroup_name
328
+
329
329
  Create a layout object passing in a layout name, multiple config subgroups to merge, and specific settings.
330
330
 
331
- my_layout = Rfm.layout 'layout_name', :other_server, :log_actions => true
332
-
331
+ my_layout = Rfm.layout 'layout_name', :other_server, :log_actions => true
332
+
333
333
  The same can be done for servers and databases.
334
334
 
335
- my_server = Rfm.server 'my.host.com'
336
- my_database = Rfm.database :development, :ssl => false, :root_cert => false
337
- my_database = Rfm.db :production
338
- # db and database are interchangeable aliases in Ginjo-rfm 2.0
339
-
335
+ my_server = Rfm.server 'my.host.com'
336
+ my_database = Rfm.database :development, :ssl => false, :root_cert => false
337
+ my_database = Rfm.db :production
338
+ # db and database are interchangeable aliases in Ginjo-rfm 2.0
339
+
340
340
  You can query your Filemaker objects for the familiar meta-data.
341
341
 
342
- my_server.databases.all.names
343
- my_server.databases['MyFmDb']
344
- my_database.layouts
345
- my_layout.value_lists
346
- my_layout.field_names
347
- my_layout.portal_meta
342
+ my_server.databases.all.names
343
+ my_server.databases['MyFmDb']
344
+ my_database.layouts
345
+ my_layout.value_lists
346
+ my_layout.field_names
347
+ my_layout.portal_meta
348
348
 
349
349
  Here are two new fun Layout methods:
350
350
 
351
- my_layout.total_count # => total records in table
352
- my_layout.count(:some_field => 'search criteria', ...) # Returns foundset_count only, no records.
351
+ my_layout.total_count # => total records in table
352
+ my_layout.count(:some_field => 'search criteria', ...) # Returns foundset_count only, no records.
353
353
 
354
354
  See the API documentation for the lowdown on new methods in Rfm Server, Database, and Layout objects.
355
355
 
@@ -359,60 +359,60 @@ All Rfm methods that take a configuration hash have two possible shortcuts.
359
359
 
360
360
  (1) If you pass a symbol before the hash, it is interpreted as subgroup specification or subgroup filter
361
361
 
362
- config :mygroup, :layout => 'mylayout'
363
- # This will add the following configuration options to the object you called 'config' on.
364
- # :use => :mygroup, :layout => 'mylayout'
365
-
366
- get_config :othergroup
367
- # This will return global configuration options merged with configuration options from :othergroup.
368
- # :use => [:mygroup, :othergroup], :layout => 'mylayout'
362
+ config :mygroup, :layout => 'mylayout'
363
+ # This will add the following configuration options to the object you called 'config' on.
364
+ # :use => :mygroup, :layout => 'mylayout'
365
+
366
+ get_config :othergroup
367
+ # This will return global configuration options merged with configuration options from :othergroup.
368
+ # :use => [:mygroup, :othergroup], :layout => 'mylayout'
369
369
 
370
370
  (2) If you pass a string before any symbols or hashes, it is interpreted as one of several possible configuration settings - usually a layout name, a database name, or a server hostname. The interpretation is dependent on the method being called. Not all methods will make use of a string parameter.
371
371
 
372
- class MyModel < Rfm::Base
373
- config 'MyLayoutName'
374
- # In this context, this is the same as
375
- # config :layout => 'MyLayoutName'
376
- end
377
-
378
- Rfm.database 'MyDatabaseName'
379
- # In this context, this is the same as
380
- # Rfm.database :database => 'MyDatabaseName'
381
-
382
- Rfm.modelize 'MyDatabaseName', :group1
383
- # In this context, this is the same as
384
- # Rfm.modelize :database => 'MyDatabaseName', :use => :group1
372
+ class MyModel < Rfm::Base
373
+ config 'MyLayoutName'
374
+ # In this context, this is the same as
375
+ # config :layout => 'MyLayoutName'
376
+ end
377
+
378
+ Rfm.database 'MyDatabaseName'
379
+ # In this context, this is the same as
380
+ # Rfm.database :database => 'MyDatabaseName'
381
+
382
+ Rfm.modelize 'MyDatabaseName', :group1
383
+ # In this context, this is the same as
384
+ # Rfm.modelize :database => 'MyDatabaseName', :use => :group1
385
385
 
386
386
  Just about anything you can do with a Rfm layout, you can also do with a Rfm model.
387
387
 
388
- MyModel.total_count
389
- MyModel.field_names
390
- MyModel.database.name
391
-
388
+ MyModel.total_count
389
+ MyModel.field_names
390
+ MyModel.database.name
391
+
392
392
  There are a number of methods within Rfm that have been made accessible from the top-level Rfm module. Note that the server/database/layout methods are new to Rfm and are not the same as Rfm::Server, Rfm::Database, and Rfm::Layout. See the above section on "Getting Rfm Server, Database, and Layout Objects Manually" for an overview of how to use the new server/database/layout methods.
393
393
 
394
- # Any of these methods can be accessed via Rfm.<method_name>
395
-
396
- Rfm::Factory :servers, :server, :db, :database, :layout, :models, :modelize
397
- Rfm::Config :config, :get_config, :config_clear
398
- Rfm::Resultset :ignore_bad_data
399
- Rfm::SaxParser :backend
400
-
394
+ # Any of these methods can be accessed via Rfm.<method_name>
395
+
396
+ Rfm::Factory :servers, :server, :db, :database, :layout, :models, :modelize
397
+ Rfm::Config :config, :get_config, :config_clear
398
+ Rfm::Resultset :ignore_bad_data
399
+ Rfm::SaxParser :backend
400
+
401
401
  If you are working with a Filemaker database that returns codes like '?' for a missing value in a date field, Rfm will throw an error. Set your main configuration, your server, or your layout to `ignore_bad_data true`, if you want Rfm to silently ignore data mismatch errors when loading resultset data. If ActiveRecord is loaded, and your resultset is loaded into a Rfm model, your model records will log these errors in the @errors attribute.
402
402
 
403
- Rfm.config :ignore_bad_data => true
404
-
405
- class MyModel < Rfm::Base
406
- config 'my_layout'
407
- end
408
-
409
- result = MyModel.find(:name => 'mike')
410
- # Assuming the Filemaker field 'some_date_field' contains a bad date value '?'
411
- result[0].errors.full_messages
412
- # ['some_date_field invalid date']
413
-
414
- # To be more specific about what objects you want to ignore data errors
415
- MyModel.layout.ignore_bad_data true
403
+ Rfm.config :ignore_bad_data => true
404
+
405
+ class MyModel < Rfm::Base
406
+ config 'my_layout'
407
+ end
408
+
409
+ result = MyModel.find(:name => 'mike')
410
+ # Assuming the Filemaker field 'some_date_field' contains a bad date value '?'
411
+ result[0].errors.full_messages
412
+ # ['some_date_field invalid date']
413
+
414
+ # To be more specific about what objects you want to ignore data errors
415
+ MyModel.layout.ignore_bad_data true
416
416
 
417
417
  ## Working with "Classic" Rfm Features
418
418
 
@@ -424,93 +424,93 @@ All of Rfm's original features and functions are available as they were before,
424
424
  IMPORTANT:SSL and Certificate verification are on by default. Please see Server#new in rdocs for explanation and setup.
425
425
  You connect with the Rfm::Server object. This little buddy will be your window into FileMaker data.
426
426
 
427
- require 'rfm'
427
+ require 'rfm'
428
428
 
429
- my_server = Rfm::Server.new(
430
- :host => 'myservername',
431
- :account_name => 'user',
432
- :password => 'pw',
433
- :ssl => false
434
- )
429
+ my_server = Rfm::Server.new(
430
+ :host => 'myservername',
431
+ :account_name => 'user',
432
+ :password => 'pw',
433
+ :ssl => false
434
+ )
435
435
 
436
436
  if your web publishing engine runs on a port other than 80, you can provide the port number as well:
437
437
 
438
- my_server = Rfm::Server.new(
439
- :host => 'myservername',
440
- :account_name => 'user',
441
- :password => 'pw',
442
- :port => 8080,
443
- :ssl => false,
444
- :root_cert => false
445
- )
438
+ my_server = Rfm::Server.new(
439
+ :host => 'myservername',
440
+ :account_name => 'user',
441
+ :password => 'pw',
442
+ :port => 8080,
443
+ :ssl => false,
444
+ :root_cert => false
445
+ )
446
446
 
447
447
  ### Databases and Layouts
448
448
 
449
449
  All access to data in FileMaker's XML interface is done through layouts, and layouts live in databases. The Rfm::Server object has a collection of databases called 'db'. So to get ahold of a database called "My Database", you can do this:
450
450
 
451
- my_db = my_server.db["My Database"]
451
+ my_db = my_server.db["My Database"]
452
452
 
453
453
  As a convenience, you can do this too:
454
454
 
455
- my_db = my_server["My Database"]
455
+ my_db = my_server["My Database"]
456
456
 
457
457
  Finally, if you want to introspect the server and find out what databases are available, you can do this:
458
458
 
459
- all_dbs = my_server.db.all
459
+ all_dbs = my_server.db.all
460
460
 
461
461
  In any case, you get back Rfm::Database objects. A database object in turn has a property called "layout":
462
462
 
463
- my_layout = my_db.layout["My Layout"]
463
+ my_layout = my_db.layout["My Layout"]
464
464
 
465
465
  Again, for convenience:
466
466
 
467
- my_layout = my_db["My Layout"]
467
+ my_layout = my_db["My Layout"]
468
468
 
469
469
  And to get them all:
470
470
 
471
- all_layouts = my_db.layout.all
471
+ all_layouts = my_db.layout.all
472
472
 
473
473
  Bringing it all together, you can do this to go straight from a server to a specific layout:
474
474
 
475
- my_layout = my_server["My Database"]["My Layout"]
475
+ my_layout = my_server["My Database"]["My Layout"]
476
476
 
477
477
  ### Working with Layouts
478
478
 
479
479
  Once you have a layout object, you can start doing some real work. To get every record from the layout:
480
480
 
481
- my_layout.all # be careful with this
481
+ my_layout.all # be careful with this
482
482
 
483
483
  To get a random record:
484
484
 
485
- my_layout.any
485
+ my_layout.any
486
486
 
487
487
  To find every record with "Arizona" in the "State" field:
488
488
 
489
- my_layout.find({"State" => "Arizona"})
489
+ my_layout.find({"State" => "Arizona"})
490
490
 
491
491
  To add a new record with my personal info:
492
492
 
493
- my_layout.create({
494
- :first_name => "Geoff",
495
- :last_name => "Coffey",
496
- :email => "gwcoffey@gmail.com"}
497
- )
493
+ my_layout.create({
494
+ :first_name => "Geoff",
495
+ :last_name => "Coffey",
496
+ :email => "gwcoffey@gmail.com"}
497
+ )
498
498
 
499
499
  Notice that in this case I used symbols instead of strings for the hash keys. The API will accept either form, so if your field names don't have whitespace or punctuation, you might prefer the symbol notation.
500
500
 
501
501
  To edit the record whose recid (filemaker internal record id) is 200:
502
502
 
503
- my_layout.edit(200, {:first_name => 'Mamie'})
503
+ my_layout.edit(200, {:first_name => 'Mamie'})
504
504
 
505
505
  Note: See the "Record Objects" section below for more on editing records.
506
506
 
507
507
  To delete the record whose recid is 200:
508
508
 
509
- my_layout.delete(200)
509
+ my_layout.delete(200)
510
510
 
511
511
  All of these methods return an Rfm::Resultset object (see below), and every one of them takes an optional parameter (the very last one) with additional options. For example, to find just a page full of records, you can do this:
512
512
 
513
- my_layout.find({:state => "AZ"}, {:max_records => 10, :skip_records => 100})
513
+ my_layout.find({:state => "AZ"}, {:max_records => 10, :skip_records => 100})
514
514
 
515
515
  For a complete list of the available options, see the "Common Options" section in the layout.rb file.
516
516
 
@@ -521,24 +521,24 @@ Finally, if filemaker returns an error when executing any of these methods, an e
521
521
 
522
522
  Any method on the Layout object that returns data will return a Resultset object. Rfm::Resultset is a subclass of Array, so first and foremost, you can use it like any other array:
523
523
 
524
- my_result = my_layout.any
525
- my_result.size # returns '1'
526
- my_result[0] # returns the first record (an Rfm::Record object)
524
+ my_result = my_layout.any
525
+ my_result.size # returns '1'
526
+ my_result[0] # returns the first record (an Rfm::Record object)
527
527
 
528
528
  The Resultset object also tells you information about the fields and portals in the result. Resultset#field\_meta and Resultset#portal\_meta are both standard Ruby hashes, with strings for keys. The fields hash has Rfm::Metadata::Field objects for values. The portals hash has another hash for its values. This nested hash is the fields on the portal. This would print out all the field names:
529
529
 
530
- my_result.field_meta.each { |name, field| puts name }
531
-
530
+ my_result.field_meta.each { |name, field| puts name }
531
+
532
532
  Or, as a convenience, you can do this:
533
533
 
534
534
  my_result.field_names
535
535
 
536
536
  This would print out the tables each portal on the layout is associated with. Below each table name, and indented, it will print the names of all the fields on each portal.
537
537
 
538
- my_result.portals.each { |table, fields|
539
- puts "table: #{table}"
540
- fields.each { |name, field| puts "\t#{name}"}
541
- }
538
+ my_result.portals.each { |table, fields|
539
+ puts "table: #{table}"
540
+ fields.each { |name, field| puts "\t#{name}"}
541
+ }
542
542
 
543
543
  Also as a convenience, you can do this:
544
544
 
@@ -546,67 +546,67 @@ Also as a convenience, you can do this:
546
546
 
547
547
  But most importantly, the Resultset contains record objects. Rfm::Record is a subclass of Hash, so it can be used in many standard ways. This code would print the value in the 'first_name' field in the first record of the Resultset:
548
548
 
549
- my_record = my_result[0]
550
- puts my_record["first_name"]
549
+ my_record = my_result[0]
550
+ puts my_record["first_name"]
551
551
 
552
552
  As a convenience, if your field names are valid Ruby method names (ie, they don't have spaces or odd punctuation in them), you can do this instead:
553
553
 
554
- puts my_record.first_name
554
+ puts my_record.first_name
555
555
 
556
556
  Since Resultsets are arrays and Records are hashes, you can take advantage of Ruby's wonderful expressiveness. For example, to get a comma-separated list of the full names of all the people in California, you could do this:
557
557
 
558
- my_layout.find(:state => 'CA').collect {|rec| "#{rec.first_name} #{rec.last_name}"}.join(", ")
558
+ my_layout.find(:state => 'CA').collect {|rec| "#{rec.first_name} #{rec.last_name}"}.join(", ")
559
559
 
560
560
  Record objects can also be edited:
561
561
 
562
- my_record.first_name = 'Isabel'
562
+ my_record.first_name = 'Isabel'
563
563
 
564
564
  Once you have made a series of edits, you can save them back to the database like this:
565
565
 
566
- my_record.save
566
+ my_record.save
567
567
 
568
568
  The save operation causes the record to be reloaded from the database, so any changes that have been made outside your script will also be picked up after the save.
569
569
 
570
570
  If you want to detect concurrent modification, you can do this instead:
571
571
 
572
- my_record.save_if_not_modified
572
+ my_record.save_if_not_modified
573
573
 
574
574
  This version will refuse to update the database and raise an error if the record was modified after it was loaded but before it was saved.
575
575
 
576
576
  Record objects also have portals. While the portals in a Resultset tell you about the tables and fields the portals show, the portals in a Record have the actual data. For example, if an Order record has Line Item records, you could do this:
577
577
 
578
- my_order = order_layout.any[0] # the [0] is important!
579
- my_lines = my_order.portals["Line Items"]
578
+ my_order = order_layout.any[0] # the [0] is important!
579
+ my_lines = my_order.portals["Line Items"]
580
580
 
581
581
  At the end of the previous block of code, my_lines is an array of Record objects. In this case, they are the records in the "Line Items" portal for the particular order record. You can then operate on them as you would any other record.
582
582
 
583
583
  NOTE: Fields on a portal have the table name and the "::" stripped off of their names if they belong to the table the portal is tied to. In other words, if our "Line Items" portal includes a quantity field and a price field, you would do this:
584
584
 
585
- my_lines[0]["Quantity"]
586
- my_lines[0]["Price"]
585
+ my_lines[0]["Quantity"]
586
+ my_lines[0]["Price"]
587
587
 
588
588
  You would NOT do this:
589
589
 
590
- my_lines[0]["Line Items::Quantity"]
591
- my_lines[0]["Line Items::Quantity"]
590
+ my_lines[0]["Line Items::Quantity"]
591
+ my_lines[0]["Line Items::Quantity"]
592
592
 
593
593
  My feeling is that the table name is redundant and cumbersome if it is the same as the portal's table. This is also up for debate.
594
594
 
595
595
  Again, you can string things together with Ruby. This will calculate the total dollar amount of the order:
596
596
 
597
- total = 0.0
598
- my_order.portals["Line Items"].each {|line| total += line.quantity * line.price}
597
+ total = 0.0
598
+ my_order.portals["Line Items"].each {|line| total += line.quantity * line.price}
599
599
 
600
600
  ### Data Types
601
601
 
602
602
  FileMaker's field types are coerced to Ruby types thusly:
603
603
 
604
- Text Field -> String object
605
- Number Field -> BigDecimal object # see below
606
- Date Field -> Date object
607
- Time Field -> DateTime object # see below
608
- TimeStamp Field -> DateTime object
609
- Container Field -> URI object
604
+ Text Field -> String object
605
+ Number Field -> BigDecimal object # see below
606
+ Date Field -> Date object
607
+ Time Field -> DateTime object # see below
608
+ TimeStamp Field -> DateTime object
609
+ Container Field -> URI object
610
610
 
611
611
  FileMaker's number field is insanely robust. The only data type in Ruby that can handle the same magnitude and precision of a FileMaker number is Ruby's BigDecimal. (This is an extension class, so you have to require 'bigdecimal' to use it yourself). Unfortuantely, BigDecimal is not a "normal" Ruby numeric class, so it might be really annoying that your tiny filemaker numbers have to go this route. This is a great topic for debate.
612
612
 
@@ -614,9 +614,9 @@ Also, Ruby doesn't have a Time type that stores just a normal time (with no date
614
614
 
615
615
  Finally, container fields will come back as URI objects. You can:
616
616
 
617
- - use Net::HTTP to download the contents of the container field using this URI
618
- - to_s the URI and use it as the src attribute of an HTML image tag
619
- - etc...
617
+ - use Net::HTTP to download the contents of the container field using this URI
618
+ - to_s the URI and use it as the src attribute of an HTML image tag
619
+ - etc...
620
620
 
621
621
  Specifically, the URI refers to the _contents_ of the container field. When accessed, the file, picture, or movie in the field will be downloaded.
622
622
 
@@ -632,13 +632,13 @@ When this is 'true' your script will dump the actual response it got from FileMa
632
632
 
633
633
  So, for an annoying, but detailed load of output, make a connection like this:
634
634
 
635
- my_server => Rfm::Server.new(
636
- :host => 'myservername',
637
- :account_name => 'user',
638
- :password => 'pw',
639
- :log_actions => true,
640
- :log_responses => true
641
- )
635
+ my_server => Rfm::Server.new(
636
+ :host => 'myservername',
637
+ :account_name => 'user',
638
+ :password => 'pw',
639
+ :log_actions => true,
640
+ :log_responses => true
641
+ )
642
642
 
643
643
  ### Source Code
644
644
 
@@ -678,8 +678,8 @@ See the changelog or the commit history for more details on changes in ginjo-rfm
678
678
  ### Version 2.1
679
679
 
680
680
  * Portals are now included by default.
681
- Removed `:include_portals` query option in favor of `:ignore_portals`.
682
- Added `:max_portal_rows` query option.
681
+ Removed `:include_portals` query option in favor of `:ignore_portals`.
682
+ Added `:max_portal_rows` query option.
683
683
  * Added field-remapping framework to allow model fields with different names than Filemaker fields.
684
684
 
685
685
  class User < Rfm::Base
@@ -716,21 +716,21 @@ See the changelog or the commit history for more details on changes in ginjo-rfm
716
716
 
717
717
 
718
718
  #### Data Modeling with ActiveModel
719
-
719
+
720
720
  If you can load ActiveModel in your project, you can have model callbacks, validations, and other ActiveModel features.
721
721
  If you can't load ActiveModel (because you're using something incompatible, like Rails 2),
722
722
  you can still use Rfm models... minus the ActiveModel-specific features like callbacks and validations. Rfm models give you basic
723
723
  data modeling with easy configuration and CRUD features.
724
724
 
725
- class User < Rfm::Base
726
- config :layout=>'user_layout'
727
- before_save :encrypt_password
728
- validate :valid_email_address
729
- end
730
-
731
- @user = User.new :username => 'bill', :password => 'pass'
732
- @user.email = 'my@email.com'
733
- @user.save!
725
+ class User < Rfm::Base
726
+ config :layout=>'user_layout'
727
+ before_save :encrypt_password
728
+ validate :valid_email_address
729
+ end
730
+
731
+ @user = User.new :username => 'bill', :password => 'pass'
732
+ @user.email = 'my@email.com'
733
+ @user.save!
734
734
 
735
735
 
736
736
  #### Choice of XML Parsers
@@ -741,31 +741,31 @@ Ginjo-rfm 2.0 uses ActiveSupport's XmlMini parsing interface, which has built-in
741
741
  LibXML, Nokogiri, and REXML. Additionally, ginjo-rfm includes adapters for Ox and Hpricot parsing.
742
742
  You can specifiy which parser to use or let Rfm decide.
743
743
 
744
- Rfm.config :parser => :libxml
744
+ Rfm.config :parser => :libxml
745
745
 
746
746
  If you're not able to install one of the faster parsers, ginjo-rfm will fall back to
747
747
  Ruby's built-in REXML. Want to roll your own XML adapter? Just pass it to Rfm as a module.
748
748
 
749
- Rfm.config :parser => MyHomeGrownAdapter
749
+ Rfm.config :parser => MyHomeGrownAdapter
750
750
 
751
751
  Choose your preferred parser globaly, as in the above example, or set a different parser for each model.
752
-
753
- class Order < Rfm::Base
754
- config :parser => :hpricot
755
- end
756
-
752
+
753
+ class Order < Rfm::Base
754
+ config :parser => :hpricot
755
+ end
756
+
757
757
  The current parsing options are
758
758
 
759
- :jdom -> JDOM (for JRuby)
760
- :oxsax -> Ox SAX
761
- :libxml -> LibXML Tree
762
- :libxmlsax -> LibXML SAX
763
- :nokogirisax -> Nokogiri SAX
764
- :nokogiri -> Nokogiri Tree
765
- :hpricot -> Hpricot Tree
766
- :rexml -> REXML Tree
767
- :rexmlsax -> REXML SAX
768
-
759
+ :jdom -> JDOM (for JRuby)
760
+ :oxsax -> Ox SAX
761
+ :libxml -> LibXML Tree
762
+ :libxmlsax -> LibXML SAX
763
+ :nokogirisax -> Nokogiri SAX
764
+ :nokogiri -> Nokogiri Tree
765
+ :hpricot -> Hpricot Tree
766
+ :rexml -> REXML Tree
767
+ :rexmlsax -> REXML SAX
768
+
769
769
 
770
770
  #### Configuration API
771
771
 
@@ -773,39 +773,39 @@ The ginjo-rfm configuration module lets you store your settings in several diffe
773
773
 
774
774
  rfm.yml
775
775
 
776
- :ssl: true
777
- :root_cert: false
778
- :timeout: 10
779
- :port: 443
780
- :host: live.mydomain.com
781
- :account_name: admin
782
- :password: pass
783
- :database: MyFmDb
776
+ :ssl: true
777
+ :root_cert: false
778
+ :timeout: 10
779
+ :port: 443
780
+ :host: live.mydomain.com
781
+ :account_name: admin
782
+ :password: pass
783
+ :database: MyFmDb
784
784
 
785
785
  Set a model's configuration.
786
-
787
- class MyModel < Rfm::Base
788
- config :layout => 'mylayout'
789
- end
786
+
787
+ class MyModel < Rfm::Base
788
+ config :layout => 'mylayout'
789
+ end
790
790
 
791
791
 
792
792
  #### Compound Filemaker Queries, with Omitable FMP Find Requests
793
793
 
794
794
  Create a Filemaker 'omit' request by including an :omit key with a value of true.
795
795
 
796
- my_layout.find :field1 => 'val1', :field2 => 'val2', :omit => true
796
+ my_layout.find :field1 => 'val1', :field2 => 'val2', :omit => true
797
797
 
798
798
  Create multiple Filemaker find requests by passing an array of hashes to the #find method.
799
799
 
800
- my_layout.find [{:field1 => 'bill', :field2 => 'admin'}, {:field2 => 'staff', :field3 => 'inactive', :omit => true}, ...]
800
+ my_layout.find [{:field1 => 'bill', :field2 => 'admin'}, {:field2 => 'staff', :field3 => 'inactive', :omit => true}, ...]
801
801
 
802
802
  If the value of a field in a find request is an array of strings, the string values will be logically OR'd in the query.
803
803
 
804
- my_layout.find :fieldOne => ['bill','mike','bob'], :fieldTwo =>'staff'
804
+ my_layout.find :fieldOne => ['bill','mike','bob'], :fieldTwo =>'staff'
805
805
 
806
806
 
807
807
  #### Full Metadata Support
808
-
808
+
809
809
  * Server databases
810
810
  * Database layouts
811
811
  * Database scripts
@@ -819,38 +819,38 @@ There are also many enhancements to make it easier to get the objects or data yo
819
819
 
820
820
  Get a database object using default config
821
821
 
822
- Rfm.db 'my_db'
822
+ Rfm.db 'my_db'
823
823
 
824
824
  Get a layout object using config grouping :my_group
825
-
826
- Rfm.layout :my_group
825
+
826
+ Rfm.layout :my_group
827
827
 
828
828
  Get the total count of all records in the table
829
829
 
830
- MyModel.total_count
830
+ MyModel.total_count
831
831
 
832
832
  Get the portal names (table-occurrence names) on the current layout
833
833
 
834
- MyModel.portal_names
834
+ MyModel.portal_names
835
835
 
836
836
  Get the names of fields on the current layout
837
837
 
838
- my_record.field_names
839
-
840
-
838
+ my_record.field_names
839
+
840
+
841
841
  ### From Version 1.4.x
842
842
 
843
843
  From ginjo-rfm 1.4.x, the following features are also included.
844
844
 
845
845
  Connection timeout settings
846
846
 
847
- Rfm.config :timeout => 10
847
+ Rfm.config :timeout => 10
848
848
 
849
849
  Value-list alternate display
850
850
 
851
- i = array_of_value_list_items[3] # => '8765'
852
- i.value # => '8765'
853
- i.display # => '8765 Amy'
851
+ i = array_of_value_list_items[3] # => '8765'
852
+ i.value # => '8765'
853
+ i.display # => '8765 Amy'
854
854
 
855
855
 
856
856