ipp_quickbase_devkit 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. data/LICENSE +87 -0
  2. data/README.rdoc +112 -0
  3. data/doc/QuickBaseClient.rb.htm +1896 -0
  4. data/doc/ReleaseNotes.txt +43 -0
  5. data/doc/qbc.makeCSVFile.qbc +4 -0
  6. data/doc/qbc.makeCSVFile.rb +4 -0
  7. data/doc/quickbase_adapter.rb.htm +399 -0
  8. data/examples/cookbookfiles/QuickBaseAPICookbook.html +2590 -0
  9. data/examples/cookbookfiles/addChangeRemoveUserRole.rb +21 -0
  10. data/examples/cookbookfiles/addOrEditRecord.rb +10 -0
  11. data/examples/cookbookfiles/application_object.rb +55 -0
  12. data/examples/cookbookfiles/applyRubyFormulas.rb +10 -0
  13. data/examples/cookbookfiles/average.rb +27 -0
  14. data/examples/cookbookfiles/backupApplication.rb +8 -0
  15. data/examples/cookbookfiles/cacheSchemas.rb +53 -0
  16. data/examples/cookbookfiles/calculateRunningTotals.rb +11 -0
  17. data/examples/cookbookfiles/copyrecords.rb +73 -0
  18. data/examples/cookbookfiles/count.rb +26 -0
  19. data/examples/cookbookfiles/createRecordNavigatorHTML.rb +42 -0
  20. data/examples/cookbookfiles/createReportDashboard.rb +35 -0
  21. data/examples/cookbookfiles/createTable.rb +12 -0
  22. data/examples/cookbookfiles/deviation.rb +25 -0
  23. data/examples/cookbookfiles/downloadCookbook.rb +97 -0
  24. data/examples/cookbookfiles/downloadFile.rb +10 -0
  25. data/examples/cookbookfiles/downloadFilesToFolder.rb +81 -0
  26. data/examples/cookbookfiles/downloadToTextFile.rb +64 -0
  27. data/examples/cookbookfiles/dumpSchema.rb +11 -0
  28. data/examples/cookbookfiles/duplicateRecord.rb +8 -0
  29. data/examples/cookbookfiles/dynamicMethods.rb +33 -0
  30. data/examples/cookbookfiles/editRecords.rb +15 -0
  31. data/examples/cookbookfiles/findJohnsLast10Records.rb +17 -0
  32. data/examples/cookbookfiles/findRubyRecords.rb +17 -0
  33. data/examples/cookbookfiles/formatCurrency.rb +24 -0
  34. data/examples/cookbookfiles/formatDate.rb +10 -0
  35. data/examples/cookbookfiles/formatDuration.rb +27 -0
  36. data/examples/cookbookfiles/formatPercent.rb +24 -0
  37. data/examples/cookbookfiles/getAllValuesForFields.rb +18 -0
  38. data/examples/cookbookfiles/getAppDTMInfo.rb +29 -0
  39. data/examples/cookbookfiles/getApplicationVariable.rb +5 -0
  40. data/examples/cookbookfiles/getChildTableDBID.rb +11 -0
  41. data/examples/cookbookfiles/getColumnListForReport.rb +6 -0
  42. data/examples/cookbookfiles/getFieldChoices.rb +13 -0
  43. data/examples/cookbookfiles/getFieldIDs.rb +6 -0
  44. data/examples/cookbookfiles/getFieldNames.rb +6 -0
  45. data/examples/cookbookfiles/getLastModTime.rb +8 -0
  46. data/examples/cookbookfiles/getLastRecModTime.rb +8 -0
  47. data/examples/cookbookfiles/getNumRecords.rb +8 -0
  48. data/examples/cookbookfiles/getNumTables.rb +4 -0
  49. data/examples/cookbookfiles/getRecord.rb +5 -0
  50. data/examples/cookbookfiles/getRecordDisplayURL.rb +13 -0
  51. data/examples/cookbookfiles/getRecordsAddedToday.rb +20 -0
  52. data/examples/cookbookfiles/getRecordsAsJSON.rb +6 -0
  53. data/examples/cookbookfiles/getReportNames.rb +25 -0
  54. data/examples/cookbookfiles/getRoleInfo.rb +48 -0
  55. data/examples/cookbookfiles/getServerStatus.rb +11 -0
  56. data/examples/cookbookfiles/getSortListForReport.rb +6 -0
  57. data/examples/cookbookfiles/getTableIDs.rb +6 -0
  58. data/examples/cookbookfiles/getTableName.rb +8 -0
  59. data/examples/cookbookfiles/getTableNames.rb +25 -0
  60. data/examples/cookbookfiles/getTimeCreated.rb +8 -0
  61. data/examples/cookbookfiles/getTimeInMilliseconds.rb +5 -0
  62. data/examples/cookbookfiles/getUserInfo.rb +26 -0
  63. data/examples/cookbookfiles/getUserRole.rb +15 -0
  64. data/examples/cookbookfiles/intranet.rb +101 -0
  65. data/examples/cookbookfiles/isAverageField.rb +17 -0
  66. data/examples/cookbookfiles/isDbidString.rb +8 -0
  67. data/examples/cookbookfiles/isTotalField.rb +16 -0
  68. data/examples/cookbookfiles/iterateDBPages.rb +8 -0
  69. data/examples/cookbookfiles/iterateFilteredRecords.rb +12 -0
  70. data/examples/cookbookfiles/iterateJoinRecords.rb +68 -0
  71. data/examples/cookbookfiles/iterateRecordInfos.rb +8 -0
  72. data/examples/cookbookfiles/iterateRecords.rb +23 -0
  73. data/examples/cookbookfiles/iterateSummaryRecords.rb +13 -0
  74. data/examples/cookbookfiles/iterateUnionRecords.rb +38 -0
  75. data/examples/cookbookfiles/listAccessibleApplications.rb +6 -0
  76. data/examples/cookbookfiles/logRequestAndResponseXML.rb +8 -0
  77. data/examples/cookbookfiles/lookupFieldPropertyByName.rb +62 -0
  78. data/examples/cookbookfiles/lookupFieldTypeByName.rb +10 -0
  79. data/examples/cookbookfiles/makeCSVFile.rb +4 -0
  80. data/examples/cookbookfiles/makeSlideShow.rb +42 -0
  81. data/examples/cookbookfiles/makerecs.rb +64 -0
  82. data/examples/cookbookfiles/max.rb +26 -0
  83. data/examples/cookbookfiles/min.rb +26 -0
  84. data/examples/cookbookfiles/percent.rb +29 -0
  85. data/examples/cookbookfiles/printChildElements.rb +54 -0
  86. data/examples/cookbookfiles/printNewRecords.rb +12 -0
  87. data/examples/cookbookfiles/processRESTRequest.rb +21 -0
  88. data/examples/cookbookfiles/provisionAndInviteNewUser.rb +13 -0
  89. data/examples/cookbookfiles/purgeRecords.rb +15 -0
  90. data/examples/cookbookfiles/quickbase_adapter.rb.htm +397 -0
  91. data/examples/cookbookfiles/quickbase_record_finder.zip +0 -0
  92. data/examples/cookbookfiles/recordAndFieldIterator.rb +24 -0
  93. data/examples/cookbookfiles/runImport.rb +9 -0
  94. data/examples/cookbookfiles/runQuickBaseTwitterConnector.rb +41 -0
  95. data/examples/cookbookfiles/sendToQuickBase.rb +33 -0
  96. data/examples/cookbookfiles/setDBvar.rb +6 -0
  97. data/examples/cookbookfiles/showRequestAndResponseXML.rb +8 -0
  98. data/examples/cookbookfiles/sqlQuery.rb +11 -0
  99. data/examples/cookbookfiles/stopOnError.rb +10 -0
  100. data/examples/cookbookfiles/sum.rb +26 -0
  101. data/examples/cookbookfiles/twitterFromQuickBase.rb +42 -0
  102. data/examples/cookbookfiles/twitterWithQuickBase.rb +36 -0
  103. data/examples/cookbookfiles/uploadCSVData.rb +20 -0
  104. data/examples/cookbookfiles/uploadExcelData.rb +22 -0
  105. data/examples/cookbookfiles/uploadFileEveryHour.rb +18 -0
  106. data/examples/cookbookfiles/uploadFileIntoNewRecord.rb +8 -0
  107. data/examples/cookbookfiles/uploadFilesFromFolder.exe +0 -0
  108. data/examples/cookbookfiles/uploadFilesFromFolder.rb +69 -0
  109. data/examples/cookbookfiles/useCompanyURL.rb +12 -0
  110. data/examples/cookbookfiles/userRoles.rb +49 -0
  111. data/examples/cookbookfiles/watchCommunityForum.rb +5 -0
  112. data/examples/cookbookfiles/wikifyTable.rb +29 -0
  113. data/examples/cookbookfiles/xmlShortcuts.rb +33 -0
  114. data/examples/pmp/app/controllers/application.rb +7 -0
  115. data/examples/pmp/app/controllers/contacts_controller.rb +8 -0
  116. data/examples/pmp/app/controllers/document_library_controller.rb +2 -0
  117. data/examples/pmp/app/controllers/issues_controller.rb +5 -0
  118. data/examples/pmp/app/controllers/projects_controller.rb +22 -0
  119. data/examples/pmp/app/controllers/resources_controller.rb +2 -0
  120. data/examples/pmp/app/controllers/tasks_controller.rb +13 -0
  121. data/examples/pmp/app/controllers/time_cards_controller.rb +5 -0
  122. data/examples/pmp/app/helpers/application_helper.rb +3 -0
  123. data/examples/pmp/app/helpers/contacts_helper.rb +2 -0
  124. data/examples/pmp/app/helpers/document_library_helper.rb +2 -0
  125. data/examples/pmp/app/helpers/issues_helper.rb +2 -0
  126. data/examples/pmp/app/helpers/projects_helper.rb +2 -0
  127. data/examples/pmp/app/helpers/resources_helper.rb +2 -0
  128. data/examples/pmp/app/helpers/tasks_helper.rb +2 -0
  129. data/examples/pmp/app/helpers/time_cards_helper.rb +2 -0
  130. data/examples/pmp/app/models/contacts.rb +26 -0
  131. data/examples/pmp/app/models/document_library.rb +2 -0
  132. data/examples/pmp/app/models/issues.rb +6 -0
  133. data/examples/pmp/app/models/projects.rb +26 -0
  134. data/examples/pmp/app/models/resources.rb +2 -0
  135. data/examples/pmp/app/models/tasks.rb +12 -0
  136. data/examples/pmp/app/models/time_cards.rb +7 -0
  137. data/examples/pmp/app/schemas/contacts.xml +1 -0
  138. data/examples/pmp/app/schemas/document_library.xml +1 -0
  139. data/examples/pmp/app/schemas/issues.xml +1 -0
  140. data/examples/pmp/app/schemas/pmp.xml +1 -0
  141. data/examples/pmp/app/schemas/projects.xml +1 -0
  142. data/examples/pmp/app/schemas/readme.txt +8 -0
  143. data/examples/pmp/app/schemas/resources.xml +1 -0
  144. data/examples/pmp/app/schemas/tasks.xml +1 -0
  145. data/examples/pmp/app/schemas/time_cards.xml +1 -0
  146. data/examples/pmp/app/views/contacts/companies.rhtml +31 -0
  147. data/examples/pmp/app/views/contacts/project_contacts.rhtml +31 -0
  148. data/examples/pmp/app/views/issues/filter_issues.rhtml +26 -0
  149. data/examples/pmp/app/views/layouts/application.rhtml +56 -0
  150. data/examples/pmp/app/views/projects/all_projects.rhtml +33 -0
  151. data/examples/pmp/app/views/projects/home.rhtml +11 -0
  152. data/examples/pmp/app/views/projects/my_open_projects.rhtml +27 -0
  153. data/examples/pmp/app/views/projects/open_projects.rhtml +44 -0
  154. data/examples/pmp/app/views/projects/project_sorted_by_company.rhtml +40 -0
  155. data/examples/pmp/app/views/projects/projects_sorted_by_priority.rhtml +30 -0
  156. data/examples/pmp/app/views/projects/updated_projects.rhtml +0 -0
  157. data/examples/pmp/app/views/tasks/all_tasks.rhtml +27 -0
  158. data/examples/pmp/app/views/tasks/search.rhtml +23 -0
  159. data/examples/pmp/app/views/tasks/search2.rhtml +23 -0
  160. data/examples/pmp/app/views/tasks/search3.rhtml +23 -0
  161. data/examples/pmp/app/views/time_cards/summary.rhtml +38 -0
  162. data/examples/pmp/config/boot.rb +45 -0
  163. data/examples/pmp/config/database.yml +30 -0
  164. data/examples/pmp/config/environment.rb +60 -0
  165. data/examples/pmp/config/environments/development.rb +21 -0
  166. data/examples/pmp/config/environments/production.rb +18 -0
  167. data/examples/pmp/config/environments/test.rb +19 -0
  168. data/examples/pmp/config/routes.rb +23 -0
  169. data/examples/pmp/db/migrate/001_create_projects.rb +10 -0
  170. data/examples/pmp/db/migrate/002_create_tasks.rb +10 -0
  171. data/examples/pmp/db/migrate/003_create_issues.rb +10 -0
  172. data/examples/pmp/db/migrate/004_create_document_libraries.rb +10 -0
  173. data/examples/pmp/db/migrate/005_create_resources.rb +10 -0
  174. data/examples/pmp/db/migrate/006_create_time_cards.rb +10 -0
  175. data/examples/pmp/db/migrate/007_create_contacts.rb +10 -0
  176. data/examples/pmp/public/404.html +30 -0
  177. data/examples/pmp/public/500.html +30 -0
  178. data/examples/pmp/public/app.index.html +277 -0
  179. data/examples/pmp/public/dispatch.cgi +10 -0
  180. data/examples/pmp/public/dispatch.fcgi +24 -0
  181. data/examples/pmp/public/dispatch.rb +10 -0
  182. data/examples/pmp/public/favicon.ico +0 -0
  183. data/examples/pmp/public/images/rails.png +0 -0
  184. data/examples/pmp/public/javascripts/application.js +2 -0
  185. data/examples/pmp/public/javascripts/controls.js +833 -0
  186. data/examples/pmp/public/javascripts/dragdrop.js +942 -0
  187. data/examples/pmp/public/javascripts/effects.js +1088 -0
  188. data/examples/pmp/public/javascripts/prototype.js +2515 -0
  189. data/examples/pmp/public/robots.txt +1 -0
  190. data/examples/pmp/test/fixtures/contacts.yml +5 -0
  191. data/examples/pmp/test/fixtures/document_libraries.yml +5 -0
  192. data/examples/pmp/test/fixtures/issues.yml +5 -0
  193. data/examples/pmp/test/fixtures/projects.yml +5 -0
  194. data/examples/pmp/test/fixtures/resources.yml +5 -0
  195. data/examples/pmp/test/fixtures/tasks.yml +5 -0
  196. data/examples/pmp/test/fixtures/time_cards.yml +5 -0
  197. data/examples/pmp/test/functional/contacts_controller_test.rb +18 -0
  198. data/examples/pmp/test/functional/document_library_controller_test.rb +18 -0
  199. data/examples/pmp/test/functional/issues_controller_test.rb +18 -0
  200. data/examples/pmp/test/functional/projects_controller_test.rb +18 -0
  201. data/examples/pmp/test/functional/resources_controller_test.rb +18 -0
  202. data/examples/pmp/test/functional/tasks_controller_test.rb +18 -0
  203. data/examples/pmp/test/functional/time_cards_controller_test.rb +18 -0
  204. data/examples/pmp/test/test_helper.rb +28 -0
  205. data/examples/pmp/test/unit/contacts_test.rb +10 -0
  206. data/examples/pmp/test/unit/document_library_test.rb +10 -0
  207. data/examples/pmp/test/unit/issues_test.rb +10 -0
  208. data/examples/pmp/test/unit/projects_test.rb +10 -0
  209. data/examples/pmp/test/unit/resources_test.rb +10 -0
  210. data/examples/pmp/test/unit/tasks_test.rb +10 -0
  211. data/examples/pmp/test/unit/time_cards_test.rb +10 -0
  212. data/lib/QuickBaseClient.rb +5054 -0
  213. data/lib/QuickBaseCommandLineClient.rb +401 -0
  214. data/lib/QuickBaseContactsAppBuilder.rb +419 -0
  215. data/lib/QuickBaseEmailer.rb +334 -0
  216. data/lib/QuickBaseEventNotifier.rb +592 -0
  217. data/lib/QuickBaseMisc.rb +96 -0
  218. data/lib/QuickBaseObjects.rb +566 -0
  219. data/lib/QuickBaseRSSGenerator.rb +286 -0
  220. data/lib/QuickBaseTextData.rb +545 -0
  221. data/lib/QuickBaseTwitterConnector.rb +300 -0
  222. data/lib/QuickBaseWebClient.rb +126 -0
  223. data/lib/WorkPlaceClient.rb +45 -0
  224. data/lib/qbc.makeCSVFile.qbc +4 -0
  225. data/lib/qbc.makeCSVFile.rb +17 -0
  226. data/lib/quickbase_adapter.rb +320 -0
  227. data/lib/runFieldEntryDialog.rb +151 -0
  228. data/lib/runOfflineFieldEntryDialog.rb +203 -0
  229. data/rakefile +100 -0
  230. data/test/run_tests.bat +7 -0
  231. data/test/spec_all_tests.rb +13 -0
  232. data/test/spec_smoke_tests.rb +58 -0
  233. data/test/spec_workplace_addrecord_test.rb +46 -0
  234. data/test/spec_workplace_base_test.rb +57 -0
  235. data/test/spec_workplace_editrecord_test.rb +38 -0
  236. data/test/spec_workplace_json_test.rb +38 -0
  237. data/test/spec_workplace_objects_test.rb +39 -0
  238. data/test/spec_workplace_smoke_tests.rb +45 -0
  239. metadata +353 -0
@@ -0,0 +1,43 @@
1
+ 06/23/09 - Changed comments to be RDoc-friendly, Split CommandLineClient and webclient into separate files.
2
+ 06/12/09 - Added dynamic creation of app,table,field,query,vars,page,role,user objects from QuickBase schemas etc.
3
+ 05/16/09 - Added support for dynamic methods and XML response searches.
4
+ 12/09/08 - Added 2 more new API calls - getAppDTMInfo and runImport
5
+ 05/06/08 - Added methods for new API calls, updated QuickBaseClient.htm.
6
+ 03/31/08 - Added QuickBaseTwitterConnector.rb, QuickBaseMisc.rb, getTableName, getTableIDs, getNumTables,
7
+ getReportNames, iterateRecordInfos, processRESTRequest.
8
+ 02/28/08 - Added listDBPages(), iterateDBPages(), getDBPagesAsArray(), obStatus(), getServerStatus().
9
+ 02/28/08 - Added addOrEditRecord(), getRecord(). Added optional validateLines parameter to import[C|T]SVFile().
10
+ 02/24/08 - Improved formatDuration()
11
+ 02/09/08 - Added getApplicationVariable[s]
12
+ 01/14/08 - Added org parameter to intialize(), added setHTTPConnection and setHTTPConnectionAndqbhost.
13
+ 11/01/07 - Fixed QuickBaseRSSGenerator.rb for Unix case-sensitivity
14
+ 10/29/07 - Updated QuickBaseClient.rb.htm help file with recently added methods.
15
+ 10/11/07 - Added sample Rails applications
16
+ 9/28/07 - Added formatCurrency, formatPercent, moved earlier release notes into .zip file.
17
+ 9/25/07 - Fixed various issues with the Rails adapter.
18
+ 9/16/07 - Added preliminary QuickBase adapter for Ruby on Rails - more info coming soon.
19
+ 8/22/07 - Improved doSQLQuery (getting ready for Rails integration!)
20
+ 7/5/07 - Added iterateSummaryRecords and supporting methods. Loops through records as if they were from a QuickBase Summary report.
21
+ 2/13/07 - Added applyPercentToRecords, applyDeviationToRecords. Set each record's percentage of a field's total, deviation from a field's average, for all records in a query.
22
+ 2/10/07 - Added iterateFilteredRecords to QuickBaseClient.rb. Filter records using regular expressions, .e.g. 'Name' starts with 'A' through 'E' .
23
+ 2/9/07 - Added min,max,sum,count,average to QuickBaseClient.rb. Applies to one or more fields from the records returned from a query.
24
+ 2/8/07 - Added iterateUnionRecords to QuickBaseClient.rb. Loops through records merged from multiple tables using common fields, like SQL UNION.
25
+ 2/7/07 - Added iterateJoinRecords to QuickBaseClient.rb. Loops through records from multiple tables joined into logical records using common values, like SQL JOIN.
26
+ 2/4/07 - Added getFieldChoices to QuickBaseClient.rb. Returns an array of choices for a multiple-choice text field.
27
+ 2/3/07 - Added iterateRecords to QuickBaseClient.rb. Simplest way to process records returned by queries.
28
+ 2/3/07 - Added editRecords to QuickBaseClient.rb; modify fields in all records matching a query.
29
+ 2/2/07 - Added replaceFieldValuePair to QuickBaseClient.rb. Good for adding multiple records that vary by one field value.
30
+ 1/27/07 - Added QuickBaseEmailer.rb. Email QuickBase data using SMTP.
31
+ 1/27/07 - Fixed runOfflineFieldEntryDialog.rb problem.
32
+ 1/21/07 - Added keyboard shortcut keys for run[Offline]FieldEntryDialog.rb
33
+ 1/10/07 - Added runOfflineFieldEntryDialog.rb. Same as above, but if not connected to QuickBase, data is cached locally and sent to QuickBase at the next opportunity.
34
+ 1/7/07 - Added runFieldEntryDialog.rb. Add records from a one-field text entry dialog. Uses the cross-platform Tk UI library that comes with Ruby.
35
+ 1/5/07 - Added QuickBaseEventNotifier.rb. Display messages or run Ruby code when records are added/modified/deleted from QuickBase tables.
36
+ 12/31/06 - Fixed errors in QuickBaseTextData.rb.
37
+ 12/24/06 - Added QuickBaseTextData.rb. Send/retrieve data in yaml-like format.
38
+ 11/3/06 - Fixed error in testQuickBaseClient()
39
+ 9/8/06 - Added QuickBaseRSSGenerator.rb file; this can be used to merge data from multiple QuickBase tables into one RSS Feed.
40
+ 9/4/06 - Added eachRecord() and eachField()
41
+ 7/5/06 - Added Brandon N's fixes for makeSVFile - THANKS Brandon!
42
+ 2/13/06 - Added more stuff to the help file.
43
+ 2/6/06 - Added direct import from Excel into a QuickBase table.
@@ -0,0 +1,4 @@
1
+ signin my_username my_password
2
+ open My QuickBase Database
3
+ exportfile MyCSVFile.csv
4
+ quit
@@ -0,0 +1,4 @@
1
+ require 'QuickBaseClient'
2
+ qbc = QuickBase::Client.new( "my_username", "my_password", "My QuickBase Database" )
3
+ qbc.makeSVFile( "MyCSVFile.csv" )
4
+ qbc.signOut
@@ -0,0 +1,399 @@
1
+ <html>
2
+ <head>
3
+ <title>
4
+ QuickBase Adapter for Ruby on Rails
5
+ </title>
6
+ </head>
7
+ <body>
8
+
9
+ <h2>Overview</h2>
10
+ The QuickBase Adapter for Ruby on Rails is primarily intended for use by developers who are probably already using
11
+ QuickBase, but who need to present QuickBase data in ways that aren't supported by the native QuickBase UI and need
12
+ to process the data in ways that aren't possible via the QuickBase UI. Developers have been able to do this using the HTML
13
+ generated from the QuickBase API, combining it with JavaScript, simple HTML forms, using the SDK's provided by QuickBase, etc.
14
+ However, being able to connect Rails to QuickBase, even in a limited fashion, opens up more options for QuickBase developers to
15
+ present and process QuickBase data in simple and powerful ways.
16
+
17
+ <hr>
18
+
19
+ <h2>Setting up</h2>
20
+ <h3>Get the Ruby wrapper for the QuickBase API</h3>
21
+ You probably already have this because you are reading this file.
22
+ The official home is <a href="https://www.quickbase.com/db/8emtadvk?a=dr&r=ztj&rl=cjtm">here</a>.
23
+ Just download the QuickBaseClient.rb.zip file attached to that QuickBase record, and unzip it into
24
+ its own folder, eg. c:\quickbase\ruby.
25
+
26
+ <h3>Install Ruby on Rails.</h3>
27
+ If you develop on Windows, Instant Rails works great.
28
+ It's very fast to install and to get up and running.
29
+ It's available <a href="http://instantrails.rubyforge.org/wiki/wiki.pl">here</a>.
30
+ <p>
31
+ You can also get all the Rails components by following the instructions from <a href="http://www.rubyonrails.org/down">http://www.rubyonrails.org/down</a>.
32
+
33
+ <h3>Learn the basics of Rails, if necessary</h3>
34
+ If you're new to Rails, go through the exercises at the beginning of the excellent <a href="http://www.pragmaticprogrammer.com/title/rails/">'Agile Development with Rails'</a> book.
35
+ The Rails homepage is <a href="http://www.rubyonrails.org/">http://www.rubyonrails.org/</a>.
36
+
37
+ <h3>Put the quickbase_adapter.rb file in the right place.</h3>
38
+ After installing Rails, search for the file <i>mysql_adapter.rb</i> on your machine. It will be in the connection_adapters folder.
39
+ Copy the quickbase_adapter.rb file into the <i>connection_adapters</i> folder.
40
+
41
+ <h3>Adjust your RUBYLIB environment variable, or edit quickbase_adapter.rb.</h3>
42
+ Skip this step if you installed the QuickBaseClient using 'gem install ipp_quickbase_devkit'.
43
+ The quickbase_adapter.rb file depends on the QuickBaseClient.rb file which you extracted from QuickBaseClient.rb.zip.
44
+ Ruby will find the QuickBaseClient.rb file if you set a RUBYLIB environment variable on your machine to include the path to the
45
+ QuickBaseClient.rb file (e.g. <i>c:\quickbase\ruby</i>). Alternatively, you can edit the quickbase_adapter.rb file and change
46
+ the <i>require 'QuickBaseClient'</i> line to include the path to the QuickBaseClient.rb file (e.g. <i>require '\quickbase\ruby\QuickBaseClient'</i>).
47
+
48
+ <h3>Make Rails aware of the QuickBase adapter</h3>
49
+ Search for the active_record.rb file in your Rails installation.
50
+ Inside the file, search for the line starting with '<i>RAILS_CONNECTION_ADAPTERS =%w(...)</i>'.
51
+ If you don't find a line containing RAILS_CONNECTION_ADAPTERS, skip this step.
52
+ Just before the closing ')', add <i> quickbase </i> to the list of adapters.
53
+
54
+ <hr>
55
+
56
+ <h2>Limitations</h2>
57
+ QuickBase does not have an SQL API, and the API it does have can't be translated to the point where Rails
58
+ developers can pretend they are dealing with an SQL database. In particular, the QuickBase API doesn't (yet) allow you
59
+ to add a table to an application; you can create a database (i.e. an 'application') with one table via the API, but you can't
60
+ add more tables to that database via the API.
61
+
62
+ <h3>Can't create tables via SQL</h3>
63
+ The adapter will not process SQL CREATE statements. However, you can use the underlying QuickBase Ruby API to
64
+ create a QuickBase 'Single Table' Application and add fields and data to it.
65
+
66
+ <h3>Doesn't support migrations.</h3>
67
+ Rails migrations involve creating and dropping tables and/or columns.
68
+ Since the adapter doesn't support creating tables using SQL, migrations aren't supported.
69
+ Also, as part of migrations, Rails expects to be able to retrieve and modify database structures by reading schema
70
+ information from the database. While this may be possible at some future date, this first release of the QuickBase adapter
71
+ does not attempt to translate Rails' schema manipulation into QuickBase API calls.
72
+
73
+ <h3>Very limited SQL SELECT support.</h3>
74
+ SELECT statements generated from Rails are translated by the QuickBase API into QuickBase's 'native' query language.
75
+ The QuickBase query language doesn't support the equivalents of JOIN, UNION, MIN, MAX, AVERAGE, COUNT, and many
76
+ other such SELECT clauses and functions. However, you can overcome these limitations using QuickBase
77
+ queries instead of SQL SELECT statements, and by setting up relationships between tables in QuickBase.
78
+
79
+ <h3>Not as fast as other databases</h3>
80
+ QuickBase is not on your server and Rails has to communicate with it by sending and receiving XML over the internet.
81
+ This isn't going to be as fast as using one of the standard SQL databases installed on the same server as Rails or within
82
+ your firewall.
83
+
84
+ <h3>Difficult to switch to another database or from another database</h3>
85
+ QuickBase is not an SQL database and the adapter doesn't support migrations.
86
+ This makes it very difficult to swap out QuickBase from your application and replace it with MySQL or
87
+ any other database. The adapter is really intended for people who are already getting
88
+ a lot of value from QuickBase itself and want to extend that value by connecting QuickBase to the Rails
89
+ framework.
90
+ <p>
91
+ If you want to switch from an SQL database to QuickBase, the QuickBase Ruby API can help copy
92
+ the data across, but wait until you've finished that job before creating your Rails application.
93
+
94
+ <hr>
95
+
96
+ <h2>Recommendations</h2>
97
+
98
+ <h3>Take full advantage of the things that are easy to do in QuickBase</h3>
99
+ QuickBase is great because of how easy it is to create tables, fields, reports, email notifications, etc.
100
+ Don't spend time doing work in Rails that is even easier to do in QuickBase.
101
+
102
+ <h3>Retrieve data using QuickBase queries instead of SQL</h3>
103
+ This will avoid all possible problems with SQL SELECT statements generated by Rails.
104
+ Queries will also run faster.
105
+ (See same subject in 'Goodies' section below.)
106
+
107
+ <h3>Define table relationships in QuickBase rather than in Rails</h3>
108
+ If you need to display and process records composed of fields from multi-tables, start in QuickBase
109
+ by creating relationships between tables, using lookup fields in Reports you define in QuickBase, then
110
+ read the data into Rails by using those Reports. This will be simpler than defining table relationships
111
+ in Rails.
112
+
113
+ <h3>Rails likes models to be singular and tables to be plural</h3>
114
+ If you use Rails scaffolds to get applications up and running quickly, don't forget that the Rails convention is
115
+ for model names to be singular and table names to be plural. e.g. if you have a table of assets, name
116
+ the QuickBase table <i>Assets</i> and name your model <i>Asset</i>. You can turn off this behavior
117
+ in Rails using <i>ActiveRecord::Base.pluralize_table_names = false</i>.
118
+
119
+ <h3>Don't use spaces in your table and field names</h3>
120
+ QuickBase allows this, but SQL doesn't. If you don't actually use any code that generates SQL
121
+ statements, you don't have to worry about this.
122
+
123
+ <h3>Don't change your table or field names after you've written code to access them</h3>
124
+ This recommendation shouldn't be unique to users of the QuickBase adapter; your existing
125
+ code will probably stop working if you do this.
126
+
127
+ <h3>Use unique names for your QuickBase applications and tables</h3>
128
+ Doing this will ensure that you can connect to tables using their names rather than their QuickBase ID's, even
129
+ though it's not a major design flaw to use the ID.
130
+
131
+ <h3>Use lowercase field names</h3>
132
+ If your users won't be viewing anything in QuickBase itself, using lowercase field names will make it easier to
133
+ use default Rails behavior.
134
+
135
+ <hr>
136
+
137
+ <h2>Goodies for QuickBase developers</h2>
138
+
139
+ <h3>Call any QuickBase API method from your model or template code</h3>
140
+ In addition to wrapping all the QuickBase HTTP API calls described in the reference document
141
+ <a href="https://www.quickbase.com/up/6mztyxu8/g/rc7/en/va/QuickBaseAPI.htm">here</a>, the Ruby wrapper for the
142
+ QuickBase API adds a number of helper methods designed reduce the amount of code you have to write
143
+ to retrieve, format, manipulate and update QuickBase data. The Ruby wrapper can be accessed directly
144
+ using <i>ActiveRecord::Base.raw_connection</i>; this will be an instance of the QuickBase::Client class
145
+ from the QuickBaseClient.rb file. Some particularly useful methods are:-
146
+ <ul>
147
+ <li>getAllValuesForFieldsAsArray - get a list of records as an Array of Hashes.
148
+ <li>iterateRecords - loop through the records returned by a QuickBase query. Use
149
+ it in view templates if you can live with bending the MVC paradigm a bit, or accumulate the records
150
+ into an @array in your controller and access that from your view.
151
+ <li>getFilteredRecords - filter records using Ruby regular expressions.
152
+ This can't be done within QuickBase and is very difficult to do with SQL.
153
+ <li>getJoinRecords - get records joined from multiple tables. This makes up for
154
+ not having the SQL version of JOIN.
155
+ <li>getUnionRecords - comparable to an SQL UNION .
156
+ <li>purgeRecords - remove all records from a table.
157
+ <li>setActiveRecord - set the record ID for subsequent record-specific calls, such as setFieldValues.
158
+ <li>setFieldValues - modify the current record using a list of field/value pairs.
159
+ <li>editRecords - modify all the records returned by a query using a list of field/value pairs.
160
+ <li>min,max,count,sum,average - SQL-type functions that are either impossible or difficult to do within
161
+ QuickBase or using the basic QuickBase API.
162
+ <li>applyPercentToRecords, applyDeviationToRecords - compute and set percentage and deviation values across multiple records.
163
+ The QuickBase UI doesn't support 'multi-record' formulas or calculations such as these.
164
+ </ul>
165
+ <p>
166
+ In addition to these and other methods which can be found in the QuickBaseClient.rb file, the Ruby wrapper comes with
167
+ a few other utility classes designed to extend the usefulness of QuickBase beyond its UI. These include an
168
+ RSS generator, for generating RSS from multiple tables, and a QuickBase event notifier that can run ruby code when
169
+ an event occurs in a QuickBase table or record.
170
+ </p>
171
+ In addition to calling these methods using the QuickBase::Client instance returned from <i>ActiveRecord::Base.raw_connection</i>,
172
+ model classes (i.e. classes derived from <i>ActiveRecord</i>) can run methods using the <i>connection.execute</i> method. In 'normal'
173
+ Rails adapters, the <i>execute</i> method is provided so you can send any SQL string directly to your database.
174
+ The equivalent of this in the QuickBase adapter is to give you direct access to methods in the QuickBase::Client class.
175
+ A simple example of this is <i>connection.execute( %q{purgeRecords("jdhfsffee")})</i>, which would remove all records from the
176
+ table with the QuickBase ID of jdhfsffee.
177
+
178
+ <h3>Retrieve data using QuickBase queries instead of SQL</h3>
179
+ If you use Rails' <i>find_by_sql</i> method and send it the name of a Report you've defined in QuickBase, or a query
180
+ expressed in the QuickBase API query language, rather than an actual SQL SELECT statement, the adapter will
181
+ return the data into an array of field/value Hashes as if you had used a SELECT statement.
182
+ An typical example is <i>find_by_sql("List All")</i>. This example will work if your model's class name matches
183
+ your QuickBase table name.
184
+ Note that Rails generates a SELECT statement whenever you use any kind of <i>find</i> method.
185
+ <p>
186
+ You can control which table to query by inserting the table name or QuickBase database ID in front of the
187
+ query, e.g. <i>find_by_sql("Assets:List All")</i>, or <i>find_by_sql("bb737sr8x:List All")</i>.
188
+ The adapater will first look in the current application for the 'Assets' table, then for an application named 'Assets', then
189
+ finally it will attempt to find the table with 'Assets' as the ID. Of course, the second example (bb737sr8x) is more
190
+ likely to succeed when the adapter looks for a QuickBase table ID. This is useful if your model's class name is different
191
+ from the corresponding QuickBase table name.
192
+ <p>
193
+ Thanks to a sneaky trick in the QuickBase adapter, if your model class reads fields from a <i>different</i>
194
+ table from the QuickBase table it is associated with, you can still retrieve field values using Active
195
+ Record's clever <i>record.field</i> syntax.
196
+
197
+ <h3>Use QuickBase field ID's in SQL SELECT statements</h3>
198
+ QuickBase fields all have an ID that doesn't change when you change the field's name.
199
+ When the QuickBase::Client parses an SQL statement, it will understand field ID's if you use them instead of
200
+ field names. It works for both the columns to SELECT and the columns to ORDER BY. You may be able
201
+ to use this to process QuickBase fields with spaces in their names.
202
+ An example would be <i>SELECT 3 FROM Assets</i> - '3' is always the 'Record ID#' field in QuickBase.
203
+
204
+ <h3>Display the QuickBase requests and responses</h3>
205
+ Put <i>printRequestsAndResponses: true</i> in your database.yml to see the XML sent to
206
+ QuickBase and received from QuickBase. This is very useful for debugging. The information
207
+ will be displayed in your Rails 'Console' window.
208
+
209
+ <h3>Cache QuickBase schemas</h3>
210
+ Put <i>cacheSchemas: true</i> in your database.yml if you are <i>sure</i> that the
211
+ schemas of the QuickBase tables used by your Rails application will not change
212
+ while your application is running. This will significantly reduce the number of
213
+ over-the-wire requests the adapter has to make to QuickBase.
214
+
215
+ <h3>Specify the precision of numeric fields in database.yml</h3>
216
+ QuickBase apparently doesn't limit the size of numeric fields.
217
+ To specify the precision of all 'decimal' fields in your application, put (e.g.) <i>decimalPrecision: 32</i>
218
+ in database.yml.
219
+
220
+ <h3>Specifiy the database using the QuickBase ID instead of the application name</h3>
221
+ In your application's database.yml file, you can use a QuickBase DBID instead of a QuickBase
222
+ application name. e.g. <i>database: bbtt9cjr6</i>.
223
+
224
+ <hr>
225
+
226
+ <h2>Sample Rails+QuickBase applications</h2>
227
+
228
+ <b><i>This section is Under Construction ... not ready yet!</i></b>
229
+ <h3>Project Manager Plus</h3>
230
+ This application demontrates various ways of retrieving and displaying data from QuickBase.
231
+ <ol>
232
+ <li>Go the the <a href="https://www.quickbase.com/db/bbtt9cjr6">QuickBase Application Library</a>.
233
+ <li>The Project Manager Plus application is <a href="https://www.quickbase.com/db/bbtt9cjr7?a=dr&rid=40">here</a>.
234
+ <li>Click on the <i>Get App</i> button to copy it to your QuickBase account.
235
+ <li>After you've copied it, be careful not to delete any of the sample data in the tables, and avoid modifying the definition
236
+ of any of the tables and fields. It's OK to add records to any of the tables.
237
+ <li>Unzip the pmp.zip file into your <i>rails_apps</i> folder. You should see the usual set of folders, with several .rb files
238
+ in the ..\pmp\app\controllers, ..\pmp\app\models, ..\pmp\app\views folders.
239
+ <li>In the ..\pmp\config\ folder, open the database.yml file and change the username and password to your
240
+ QuickBase username and password.
241
+ <li>Start Rails with the usual <i>ruby script/server</i> command.
242
+ <li>Point your browser at the appropriate host and port, e.g. <i>http://localhost:3000/</i>, to connect to Rails.
243
+ <li>Click on the links on the left of the screen to see different ways of retrieving records from QuickBase.
244
+ The pages are deliberately uninteresting in appearance in order to simplify the MVC code to focus on reading records.
245
+ </ol>
246
+
247
+ <h3>Contacts database</h3>
248
+ This application demonstrates basic CRUD operations, and how to generate a QuickBase database and a Rails app for it.
249
+
250
+ <ol>
251
+ <li>Put the <i>QuickBaseContactsAppBuilder.rb</i> file in your rails_apps folder.
252
+ <li>From the command line in the rails_apps folder, type <i>ruby QuickBaseContactsAppBuilder.rb username password</i>.
253
+ <i>username</i> and <i>password</i> should be your QuickBase username and password. This should generate a rails
254
+ app named <i>&lt;username&gt;_contacts</i> and an application in QuickBase with the same name. The QuickBase
255
+ application is a single table application.
256
+ <li>From the <i>&lt;username&gt;_contacts</i> folder, run <i>ruby script/server</i>.
257
+ <li>Point your browser at the appropriate host and port, e.g. <i>http://localhost:3000/</i>, to connect to Rails.
258
+ </ol>
259
+
260
+ <hr>
261
+
262
+ <h2>Under the Hood</h2>
263
+
264
+ The Ruby wrapper for the QuickBase API has evolved over 18 months from being a thin wrapper around the
265
+ QuickBase HTTP API to a small library of methods that reduce the work you have to do to get common and
266
+ important things done using QuickBase. Several methods were added to make the QuickBase Rails adapter
267
+ work, so the adapter could remain small and the Ruby wrapper could provide more functionality to anyone
268
+ using it without Rails.
269
+ <p>
270
+ One could argue that the QuickBase API could be used directly from within Rails models, views
271
+ and controllers without going through the adapter. That is certainly true and some applications might work better that way.
272
+ However, the adapter helps developers work more in the 'Rails way' and definitely saves time as you add more Rails applications.
273
+ It's also technically possible to largely bypass Active Record and use the Rails MVC framework by processing lists of records
274
+ from QuickBase as Arrays of Hashes, but you will lose the benefits of Active Record by doing this.
275
+
276
+ <h3>Applications and Tables</h3>
277
+
278
+ As with all the Rails adapters, the QuickBase adapter encapsulates the over-the-wire connection to the database so that
279
+ the database.yml file in your application is the only thing you have to modify to connect to the appropriate QuickBase
280
+ application, e.g. -
281
+
282
+ <pre>
283
+
284
+ development:
285
+ adapter: quickbase
286
+ database: myQuickBaseApplication
287
+ username: myQuickBaseUsername
288
+ password: myQuickBasePassword
289
+
290
+ </pre>
291
+
292
+ This is enough information for the QuickBase adapter to create a QuickBase::Client that connects to your QuickBase
293
+ application using a valid username and password. The QuickBase::Client connection is then accessible in your Rails code
294
+ using <i>ActiveRecord::Base.raw_connection</i>.
295
+
296
+ <p>
297
+ A QuickBase 'application' is a set of one or more tables accessible to a selected group of users via a 'Dashboard' and a menu.
298
+ However, the QuickBase API treats tables as independent things and 'applications' are only visible to the API as a parent table
299
+ with a set of child tables. If your application is a 'Single-table' application, the API sees the application as just a table. With applications
300
+ that start out as a 'Single-table' application then later become 'Multi-table', the name of the application is also the name of
301
+ the 'Single' table you started with. The 'database' line in your database.yml file can be the name of a application or a table. Either way,
302
+ the name of the application or table in your database.yml should be unique for the 'myQuickBaseUsername' user, to help avoid connecting to
303
+ the wrong table or application.
304
+ <p>
305
+ When the QuickBase adapter processes an SQL SELECT statement, it uses the table name in the FROM clause to find the
306
+ correct table in your application, by looking through the list of child tables if necessary. As with all the QuickBase::Client
307
+ methods that access tables, once you have accessed a table, that table is the default for any subsequent QuickBase::Client
308
+ method calls. QuickBase::Client.dbid contains the ID of the last accessed QuickBase table. This saves you having to find
309
+ a table between every API call to do something with the same table.
310
+ <p>
311
+ You can also access tables that aren't in the QuickBase application specified in database.yml if your model name matches
312
+ the name of a different application. You can also access any QuickBase table from any application if you use QuickBase
313
+ queries instead of SQL SELECT statements. This is not possible using the other SQL database Rails adapters . To see exactly
314
+ how the adapter does this, look at the <i>select</i> and <i>setActiveTable</i> methods in quickbase_adapter.rb.
315
+
316
+ <h3>Columns and Fields</h3>
317
+ The QuickBase adapter supports the Rails convention of dynamically reading the list of columns from the active table.
318
+ In QuickBase, 'columns' are referred to as 'fields'. The adapter attempts to accomodate spaces you might be using
319
+ in your QuickBase field names, but spaces in field names might be a problem when you let Rails add or update QuickBase
320
+ records via SQL INSERT and UPDATE statements.
321
+ <p>
322
+ When fields are read from QuickBase and turned into columns for Rails, the adapter makes it's best guess as to the display format that
323
+ should be used for each field, as well as the default value for each field. The adapter assumes that numeric fields will not
324
+ have decimal places unless the number of places is specificied in QuickBase. Look at the <i>columns</i> method in quickbase_adapter.rb
325
+ to see exactly what it does.
326
+ <p>
327
+ Note that if you use <i>cacheSchemas: true</i> in your database.yml, the adapter will retrieve each QuickBase table's
328
+ schema only once, so it's a bad idea to remove or modify fields in those QuickBase tables while Rails is interacting
329
+ with them. Using <i>cacheSchemas: true</i> can knock several seconds off the time it takes to read any amount of
330
+ data from QuickBase.
331
+ <p>
332
+ When you let Rails find records via SQL SELECT (generated by <i>find</i> calls), or by using <i>find_by_sql</i> using
333
+ a QuickBase query, the adapter copies the table's "Record ID#" field to an "id" column so that subsequent UPDATE and DELETE
334
+ calls will know what record to operate on. If you retrieve records directly via the QuickBase::Client in your code, you may
335
+ also have to copy the key field to an "id" column in order to make subsequent UPDATE and DELETE calls to QuickBase
336
+ via the default Rails actions for editing and destroying records.
337
+ <p>
338
+ If your table has a key field that is different from the Record ID#, the adapter makes Rails aware that it is the primary key field.
339
+ However, note that the Record ID# field, or whatever you may have renamed it to, is always used to retrieve and update specific records.
340
+ <p>
341
+ QuickBase tables all have a number of 'built-in' fields, which are read-only. By default ,the QuickBase adapter makes these fields
342
+ unavailable for editing in Rails by renaming those fields to make Rails exclude them from its list of 'content' columns. It
343
+ does this by appending "_id" the those fields' names. The 'built-in' fields are:-
344
+
345
+ <ul>
346
+ <li>Date Created
347
+ <li>Date Modified
348
+ <li>Record Owner
349
+ <li>Last Modified By
350
+ </ul>
351
+
352
+ <p>
353
+ <i>Record ID#</i> is also a 'built-in' QuickBase field but is usually copied to "id", as described above.
354
+ <p>
355
+
356
+ QuickBase lets you change the name of these built-in fields, but the adapter looks at their ID's rather
357
+ than their names. These fields can still be displayed in your views if you access them
358
+ using (e.g.) <i>record["Date Created"]</i>.
359
+
360
+ <h3>Queries</h3>
361
+
362
+ The QuickBase adapter's <i>select</i> method processes all queries.
363
+ <ul>
364
+ <li>
365
+ A query string starting with <i>SELECT</i> is presumed to be an SQL SELECT statement.
366
+ The adapter sends this to the <i>QuickBase::Client.doSQLQuery()</i> method, in QuickBaseClient.rb.
367
+ This method does its best to parse the SQL and translate it into a query expressed in the QuickBase query language.
368
+ The only SQL keywords it can handle are <i>SELECT, count(*), FROM, WHERE, ORDER BY, LIMIT, OFFSET</i>.
369
+ The field names in the SELECT and WHERE clauses can be QuickBase field ID's instead of names, which is useful for
370
+ QuickBase field names that contain spaces.
371
+ <p>
372
+ Any variation of the ActiveRecord <i>find</i> method will result in an SQL SELECT statement.
373
+ For fields that do not contain spaces in their names, you can use ActiveRecord's
374
+ dynamic <i>find_by_??</i> and <i>find_all_by_??</i> methods, e.g. <i>find_all_by_status("Complete")</i>.
375
+ <li>
376
+ A query string starting with <i>{</i> and ending with <i>}</i> is assumed to be a query expressed in the QuickBase
377
+ query language. This is sent 'as is' to QuickBase.
378
+ To understand the QuickBase query language, read the section towards the bottom of <a href="https://www.quickbase.com/up/6mztyxu8/g/rc7/en/va/QuickBaseAPI.htm">QuickBaseAPI.htm</a>.
379
+ <li>
380
+ Any other query string is assumed to be the name of a Report defined in QuickBase.
381
+ If the string contains a colon (':'), any text before the colon will be treated as the name or ID of the QuickBase
382
+ table to query. Look at the adapter's <i>setActiveTable</i> method to understand how the correct QuickBase table
383
+ is located for the query.
384
+
385
+ </ul>
386
+ <p>
387
+ The <i>select</i> method returns an Array of records, each record being a Hash of field/value pairs.
388
+ This is what ActiveRecord expects. ActiveRecord expects each field to have a corresponding column; see the adapter's
389
+ <i>columns</i> method and its QuickBaseColumn class to understand how the adapter provides what ActiveRecord
390
+ expects.
391
+ <p>
392
+ The raw data returned from QuickBase is not formatted as it appears in QuickBase.
393
+ E.g. date, currency and percent field values are unformatted. The QuickBase::Client class formats
394
+ these field values appropriately before returning them, but if you bypass ActiveRecord by accessing
395
+ QuickBase::Client methods directly, or via the adapter's <i>execute</i> method, you must format
396
+ the raw data in your code. Rails has helper methods for formatting data.
397
+
398
+ </body>
399
+ </html>