captproton-restfulx 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/README.rdoc +50 -0
  2. data/Rakefile +79 -0
  3. data/VERSION.yml +4 -0
  4. data/app_generators/rx_app/USAGE +22 -0
  5. data/app_generators/rx_app/rx_app_generator.rb +110 -0
  6. data/app_generators/rx_app/templates/actionscript.properties +16 -0
  7. data/app_generators/rx_app/templates/actionscriptair.properties +16 -0
  8. data/app_generators/rx_app/templates/app.yaml.erb +12 -0
  9. data/app_generators/rx_app/templates/default_tasks.rake +38 -0
  10. data/app_generators/rx_app/templates/empty.txt +0 -0
  11. data/app_generators/rx_app/templates/expressInstall.swf +0 -0
  12. data/app_generators/rx_app/templates/flex.properties +2 -0
  13. data/app_generators/rx_app/templates/generate.rb +17 -0
  14. data/app_generators/rx_app/templates/html-template/AC_OETags.js +276 -0
  15. data/app_generators/rx_app/templates/html-template/history/history.css +6 -0
  16. data/app_generators/rx_app/templates/html-template/history/history.js +645 -0
  17. data/app_generators/rx_app/templates/html-template/history/historyFrame.html +29 -0
  18. data/app_generators/rx_app/templates/html-template/index.template.html +121 -0
  19. data/app_generators/rx_app/templates/html-template/playerProductInstall.swf +0 -0
  20. data/app_generators/rx_app/templates/index.html.erb +18 -0
  21. data/app_generators/rx_app/templates/index.yaml +11 -0
  22. data/app_generators/rx_app/templates/mainair-app.xml +134 -0
  23. data/app_generators/rx_app/templates/mainapp-config.xml +22 -0
  24. data/app_generators/rx_app/templates/mainapp.mxml +152 -0
  25. data/app_generators/rx_app/templates/project-textmate.erb +72 -0
  26. data/app_generators/rx_app/templates/project.properties +18 -0
  27. data/app_generators/rx_app/templates/projectair.properties +24 -0
  28. data/app_generators/rx_app/templates/restfulx.yml +46 -0
  29. data/app_generators/rx_app/templates/swfobject.js +5 -0
  30. data/bin/rx-gen +31 -0
  31. data/lib/restfulx.rb +90 -0
  32. data/lib/restfulx/active_foo.rb +181 -0
  33. data/lib/restfulx/active_record_tasks.rb +90 -0
  34. data/lib/restfulx/active_record_uuid_helper.rb +17 -0
  35. data/lib/restfulx/configuration.rb +75 -0
  36. data/lib/restfulx/datamapper_foo.rb +81 -0
  37. data/lib/restfulx/rails/recipes.rb +60 -0
  38. data/lib/restfulx/rails/schema_to_yaml.rb +112 -0
  39. data/lib/restfulx/rails/schema_to_yaml/extensions/enumerable.rb +8 -0
  40. data/lib/restfulx/rails/schema_to_yaml/settings/config.rb +17 -0
  41. data/lib/restfulx/rails/schema_to_yaml/settings/core.rb +73 -0
  42. data/lib/restfulx/rails/swf_helper.rb +59 -0
  43. data/lib/restfulx/tasks.rb +110 -0
  44. data/rails_generators/rx_config/USAGE +19 -0
  45. data/rails_generators/rx_config/rx_config_generator.rb +151 -0
  46. data/rails_generators/rx_config/templates/actionscript.properties +16 -0
  47. data/rails_generators/rx_config/templates/actionscriptair.properties +16 -0
  48. data/rails_generators/rx_config/templates/expressInstall.swf +0 -0
  49. data/rails_generators/rx_config/templates/flex.properties +2 -0
  50. data/rails_generators/rx_config/templates/flex_controller.erb +4 -0
  51. data/rails_generators/rx_config/templates/html-template/AC_OETags.js +276 -0
  52. data/rails_generators/rx_config/templates/html-template/history/history.css +6 -0
  53. data/rails_generators/rx_config/templates/html-template/history/history.js +645 -0
  54. data/rails_generators/rx_config/templates/html-template/history/historyFrame.html +29 -0
  55. data/rails_generators/rx_config/templates/html-template/index.template.html +121 -0
  56. data/rails_generators/rx_config/templates/html-template/playerProductInstall.swf +0 -0
  57. data/rails_generators/rx_config/templates/index.erb +16 -0
  58. data/rails_generators/rx_config/templates/mainair-app.xml +134 -0
  59. data/rails_generators/rx_config/templates/mainapp-config.xml +22 -0
  60. data/rails_generators/rx_config/templates/mainapp.mxml +129 -0
  61. data/rails_generators/rx_config/templates/project-textmate.erb +72 -0
  62. data/rails_generators/rx_config/templates/project.properties +18 -0
  63. data/rails_generators/rx_config/templates/projectair.properties +24 -0
  64. data/rails_generators/rx_config/templates/restfulx.erb +75 -0
  65. data/rails_generators/rx_config/templates/restfulx.yml +65 -0
  66. data/rails_generators/rx_config/templates/restfulx_tasks.rake +9 -0
  67. data/rails_generators/rx_config/templates/routes.erb +47 -0
  68. data/rails_generators/rx_config/templates/session_store_flash.erb +1 -0
  69. data/rails_generators/rx_config/templates/swfobject.js +5 -0
  70. data/rails_generators/rx_controller/USAGE +10 -0
  71. data/rails_generators/rx_controller/rx_controller_generator.rb +31 -0
  72. data/rails_generators/rx_controller/templates/controller.as.erb +38 -0
  73. data/rails_generators/rx_main_app/USAGE +8 -0
  74. data/rails_generators/rx_main_app/rx_main_app_generator.rb +60 -0
  75. data/rails_generators/rx_main_app/templates/mainapp.mxml +129 -0
  76. data/rails_generators/rx_scaffold/USAGE +35 -0
  77. data/rails_generators/rx_scaffold/rx_scaffold_generator.rb +242 -0
  78. data/rails_generators/rx_scaffold/templates/controllers/default.rb.erb +125 -0
  79. data/rails_generators/rx_scaffold/templates/controllers/resource_controller.rb.erb +23 -0
  80. data/rails_generators/rx_scaffold/templates/fixtures.yml.erb +39 -0
  81. data/rails_generators/rx_scaffold/templates/functional_test.rb +45 -0
  82. data/rails_generators/rx_scaffold/templates/helper_test.rb +4 -0
  83. data/rails_generators/rx_scaffold/templates/layouts/default.erb +167 -0
  84. data/rails_generators/rx_scaffold/templates/migration.rb.erb +46 -0
  85. data/rails_generators/rx_scaffold/templates/model.as.erb +73 -0
  86. data/rails_generators/rx_scaffold/templates/model.rb.erb +46 -0
  87. data/rails_generators/rx_yaml_scaffold/USAGE +51 -0
  88. data/rails_generators/rx_yaml_scaffold/rx_yaml_scaffold_generator.rb +68 -0
  89. data/rxgen_generators/rx_config/USAGE +5 -0
  90. data/rxgen_generators/rx_config/rx_config_generator.rb +21 -0
  91. data/rxgen_generators/rx_controller/USAGE +10 -0
  92. data/rxgen_generators/rx_controller/rx_controller_generator.rb +41 -0
  93. data/rxgen_generators/rx_controller/templates/assist.py +65 -0
  94. data/rxgen_generators/rx_controller/templates/controller.as.erb +38 -0
  95. data/rxgen_generators/rx_controller/templates/iso8601.py +92 -0
  96. data/rxgen_generators/rx_controller/templates/restful.py +136 -0
  97. data/rxgen_generators/rx_main_app/USAGE +8 -0
  98. data/rxgen_generators/rx_main_app/rx_main_app_generator.rb +65 -0
  99. data/rxgen_generators/rx_main_app/templates/main.py.erb +29 -0
  100. data/rxgen_generators/rx_main_app/templates/mainapp.mxml +152 -0
  101. data/rxgen_generators/rx_scaffold/USAGE +29 -0
  102. data/rxgen_generators/rx_scaffold/rx_scaffold_generator.rb +194 -0
  103. data/rxgen_generators/rx_scaffold/templates/controller.py.erb +27 -0
  104. data/rxgen_generators/rx_scaffold/templates/layouts/default.erb +167 -0
  105. data/rxgen_generators/rx_scaffold/templates/model.as.erb +73 -0
  106. data/rxgen_generators/rx_scaffold/templates/model.py.erb +14 -0
  107. data/rxgen_generators/rx_yaml_scaffold/USAGE +45 -0
  108. data/rxgen_generators/rx_yaml_scaffold/rx_yaml_scaffold_generator.rb +47 -0
  109. data/spec/restfulx_spec.rb +4 -0
  110. data/spec/spec_helper.rb +13 -0
  111. data/tasks/restfulx.rake +2 -0
  112. data/test/rails/controllers/application_controller.rb +15 -0
  113. data/test/rails/controllers/locations_controller.rb +93 -0
  114. data/test/rails/controllers/notes_controller.rb +96 -0
  115. data/test/rails/controllers/projects_controller.rb +93 -0
  116. data/test/rails/controllers/tasks_controller.rb +93 -0
  117. data/test/rails/controllers/users_controller.rb +93 -0
  118. data/test/rails/database.yml +4 -0
  119. data/test/rails/fixtures/locations.yml +8 -0
  120. data/test/rails/fixtures/notes.yml +17 -0
  121. data/test/rails/fixtures/projects.yml +25 -0
  122. data/test/rails/fixtures/simple_properties.yml +19 -0
  123. data/test/rails/fixtures/tasks.yml +46 -0
  124. data/test/rails/fixtures/users.yml +13 -0
  125. data/test/rails/helpers/functional_test_helper.rb +21 -0
  126. data/test/rails/helpers/test_helper.rb +54 -0
  127. data/test/rails/helpers/unit_test_helper.rb +29 -0
  128. data/test/rails/model.yml +35 -0
  129. data/test/rails/models/location.rb +4 -0
  130. data/test/rails/models/note.rb +3 -0
  131. data/test/rails/models/project.rb +4 -0
  132. data/test/rails/models/simple_property.rb +2 -0
  133. data/test/rails/models/task.rb +18 -0
  134. data/test/rails/models/user.rb +20 -0
  135. data/test/rails/schema.rb +77 -0
  136. data/test/rails/test.swf +1 -0
  137. data/test/rails/test_active_foo.rb +36 -0
  138. data/test/rails/test_rails_integration_functional.rb +22 -0
  139. data/test/rails/test_to_fxml.rb +35 -0
  140. data/test/rails/test_to_json.rb +23 -0
  141. data/test/rails/views/notes/empty_params_action.html.erb +1 -0
  142. data/test/rails/views/notes/index.html.erb +1 -0
  143. metadata +234 -0
@@ -0,0 +1,90 @@
1
+ # ActiveRecord specific Rake tasks. Namely, nice little extras such as:
2
+ # - db:mysql:stage
3
+ # - db:refresh
4
+ require File.join(File.dirname(__FILE__), 'tasks')
5
+ require File.join(File.dirname(__FILE__), 'rails', 'schema_to_yaml')
6
+
7
+ # stores local copy of the application environment ('production', 'test', etc)
8
+ # so that appropriate values in config/database.yml are used
9
+ APP_ENV = defined?(ENV['RAILS_ENV']) ? ENV['RAILS_ENV'] : ENV['MERB_ENV']
10
+
11
+ namespace :db do
12
+ namespace :mysql do
13
+ namespace :stage do
14
+ desc "Stage production, test and development databases"
15
+ task :all do
16
+ db_names = %w(development test production)
17
+ admin_password = ENV["ADMINPASS"] || ""
18
+ db_user_name = ENV["USER"] || "root"
19
+ db_password = ENV["PASS"] || ""
20
+ stage_database(db_names, admin_password, db_user_name, db_password)
21
+ end
22
+ end
23
+
24
+ desc "Stage the database environment for #{APP_ENV}"
25
+ task :stage do
26
+ db_names = [APP_ENV]
27
+ admin_password = ENV["ADMINPASS"] || ""
28
+ db_user_name = ENV["USER"] || "root"
29
+ db_password = ENV["PASS"] || ""
30
+ stage_database(db_names, admin_password, db_user_name, db_password)
31
+ end
32
+ end
33
+
34
+ # Performs MySQL database set-up based on the username and password
35
+ # provided. Also updates Rails config/database.yml file with database
36
+ # username and password
37
+ def stage_database(db_names, admin_password, db_user_name, db_password)
38
+ sql_command = ""
39
+
40
+ db_names.each do |name|
41
+ db_name = ActiveRecord::Base.configurations[name]['database']
42
+ sql_command += "drop database if exists #{db_name}; " <<
43
+ "create database #{db_name}; grant all privileges on #{db_name}.* " <<
44
+ "to #{db_user_name}@localhost identified by \'#{db_password}\';"
45
+ ActiveRecord::Base.configurations[name]['username'] = db_user_name
46
+ ActiveRecord::Base.configurations[name]['password'] = db_password
47
+ end
48
+
49
+ if (!File.exist?("#{APP_ROOT}/tmp/stage.sql"))
50
+ File.open("#{APP_ROOT}/tmp/stage.sql", "w") do |file|
51
+ file.print sql_command
52
+ end
53
+ end
54
+
55
+ # back up the original database.yml file just in case
56
+ File.copy("#{APP_ROOT}/config/database.yml",
57
+ "#{APP_ROOT}/config/database.yml.sample") if !File.exist?("#{APP_ROOT}/config/database.yml.sample")
58
+
59
+ dbconfig = File.read("#{APP_ROOT}/config/database.yml")
60
+ dbconfig.gsub!(/username:.*/, "username: #{db_user_name}")
61
+ dbconfig.gsub!(/password:.*/, "password: #{db_password}")
62
+
63
+ File.open("#{APP_ROOT}/config/database.yml", "w") do |file|
64
+ file.print dbconfig
65
+ end
66
+
67
+ if system %(mysql -h localhost -u root --password=#{admin_password} < tmp/stage.sql)
68
+ puts "Updated config/database.yml and staged the database based on your settings"
69
+ File.delete("tmp/stage.sql") if File.file?("tmp/stage.sql")
70
+ else
71
+ puts "Staging was not performed. Check console for errors. It is possible that 'mysql' executable was not found."
72
+ end
73
+ end
74
+
75
+ desc "Drop the database environment for #{APP_ENV} only if it exists"
76
+ task :drop_if_exists do
77
+ Rake::Task["db:drop"].invoke rescue nil
78
+ end
79
+
80
+ desc "Refresh the database environment for #{APP_ENV}"
81
+ task :refresh => ['db:drop_if_exists', 'db:create', 'db:migrate', 'db:fixtures:load']
82
+
83
+ # used to analyze your schema and dump out a model.yml file for converting old rails projects
84
+ namespace :schema do
85
+ desc "Create model.yml from schema.rb"
86
+ task :to_yaml => :environment do
87
+ SchemaToYaml.schema_to_yaml
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,17 @@
1
+ # Patches ActiveRecord models to use UUID based IDs instead of the default numeric ones
2
+ require 'uuidtools'
3
+
4
+ # Extends ActiveRecord models with UUID based IDs
5
+ module RestfulX
6
+ module UUIDHelper
7
+ def self.included(base)
8
+ base.class_eval do
9
+ before_create :generate_uuid
10
+ end
11
+ end
12
+
13
+ def generate_uuid
14
+ self.id = UUIDTools::UUID.random_create.to_s.gsub("-", "") unless self.id
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,75 @@
1
+ # Interestingly enough there's no way to *just* upper-case or down-case first letter of a given
2
+ # string. Ruby's own +capitalize+ actually downcases all the rest of the characters in the string
3
+ # We patch the class to add our own implementation.
4
+ require "yaml"
5
+ require "erb"
6
+ require File.dirname(__FILE__) + "/rails/schema_to_yaml/settings/config"
7
+ require File.dirname(__FILE__) + "/rails/schema_to_yaml/settings/core"
8
+
9
+ Dir[File.dirname(__FILE__) + "/rails/schema_to_yaml/extensions/*.rb"].each do |f|
10
+ require f
11
+ end
12
+
13
+ class String
14
+ # Upper-case first character of a string leave the rest of the string intact
15
+ def ucfirst
16
+ self[0,1].capitalize + self[1..-1]
17
+ end
18
+
19
+ # Down-case first character of a string leaving the rest of it intact
20
+ def dcfirst
21
+ self[0,1].downcase + self[1..-1]
22
+ end
23
+ end
24
+
25
+ # Primary RestfulX configuration options
26
+ module RestfulX
27
+ # Computes necessary configuration options from the environment. This can be used in Rails, Merb
28
+ # or standalone from the command line.
29
+ module Configuration
30
+ # We try to figure out the application root using a number of possible options
31
+ APP_ROOT = defined?(RAILS_ROOT) ? RAILS_ROOT : defined?(Merb) ? Merb.root : File.expand_path(".")
32
+
33
+ RxSettings = SchemaToYaml::Settings::Core
34
+
35
+ # Extract project, package, controller name, etc from the environment. This will respect
36
+ # config/restfulx.yml if it exists, you can override all of the defaults there.
37
+ def extract_names(project = nil)
38
+ if project
39
+ project_name = project.downcase.gsub(/\W/, '')
40
+ flex_project_name = project_name.camelize
41
+ else
42
+ project_name = APP_ROOT.split("/").last.gsub(/\W/, '')
43
+ flex_project_name = project_name.camelize
44
+ end
45
+
46
+ # give a chance to override the settings via restfulx.yml
47
+ begin
48
+ config = YAML.load(File.open("#{APP_ROOT}/config/restfulx.yml"))
49
+ base_package = config['base_package'] || flex_project_name.downcase
50
+ base_folder = base_package.gsub('.', '/')
51
+ project_name = config['project_name'].downcase.gsub(/\W/, '') || project_name
52
+ flex_project_name = project_name.camelize
53
+ controller_name = config['controller_name'] || "ApplicationController"
54
+ flex_root = config['flex_root'] || "app/flex"
55
+ distributed = config['distributed'] || false
56
+ rescue
57
+ base_folder = base_package = flex_project_name.downcase
58
+ controller_name = "ApplicationController"
59
+ flex_root = "app/flex"
60
+ distributed = false
61
+ end
62
+ [project_name, flex_project_name, controller_name, base_package, base_folder, flex_root, distributed]
63
+ end
64
+
65
+ # List files ending in *.as (ActionScript) in a given folder
66
+ def list_as_files(dir_name)
67
+ Dir.entries(dir_name).grep(/\.as$/).map { |name| name.sub(/\.as$/, "") }.join(", ")
68
+ end
69
+
70
+ # List files ending in *.mxml in a given folder
71
+ def list_mxml_files(dir_name)
72
+ Dir.entries(dir_name).grep(/\.mxml$/).map { |name| name.sub(/\.mxml$/, "") }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,81 @@
1
+ # Flex friendly DataMapper patches, more specifically we just add +to_xml+ on
2
+ # ValidationErrors class
3
+ require 'dm-serializer/common'
4
+ require 'dm-serializer/xml_serializers'
5
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'restfulx') if !defined?(RestfulX)
6
+
7
+ # RestfulX datamapper patches
8
+ module DataMapper
9
+
10
+ # Monkey patches dm-serialization to_json method to add ruby_class: YourClass
11
+ # to all serialized objects
12
+ module Serialize
13
+ # Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)
14
+ #
15
+ # @return <String> a JSON representation of the Resource
16
+ def to_json(*args)
17
+ options = args.first || {}
18
+ result = '{ '
19
+ fields = []
20
+
21
+ propset = properties_to_serialize(options)
22
+
23
+ fields += propset.map do |property|
24
+ "#{property.name.to_json}: #{send(property.getter).to_json}"
25
+ end
26
+
27
+ fields << "\"ruby_class\": #{self.class.to_json}"
28
+
29
+ # add methods
30
+ (options[:methods] || []).each do |meth|
31
+ if self.respond_to?(meth)
32
+ fields << "#{meth.to_json}: #{send(meth).to_json}"
33
+ end
34
+ end
35
+
36
+ # Note: if you want to include a whole other model via relation, use :methods
37
+ # comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
38
+ # add relationships
39
+ # TODO: This needs tests and also needs to be ported to #to_xml and #to_yaml
40
+ (options[:relationships] || {}).each do |rel,opts|
41
+ if self.respond_to?(rel)
42
+ fields << "#{rel.to_json}: #{send(rel).to_json(opts)}"
43
+ end
44
+ end
45
+
46
+ result << fields.join(', ')
47
+ result << ' }'
48
+ result
49
+ end
50
+ end
51
+
52
+ # see DataMapper docs for more details
53
+ module Validate
54
+ # By default DataMapper validation errors doesn't have +to_xml+ method. This is
55
+ # actually very useful when dealing with remote stateful clients such as Flex/AIR.
56
+ class ValidationErrors
57
+ # Add Flex-friendly +to_xml+ implementation
58
+ def to_xml
59
+ xml = DataMapper::Serialize::XMLSerializers::SERIALIZER
60
+ doc ||= xml.new_document
61
+ root = xml.root_node(doc, "errors")
62
+ @errors.each_key do |attribute|
63
+ @errors[attribute].each do |msg|
64
+ next if msg.nil?
65
+ if attribute == "base"
66
+ xml.add_node(root, "error", nil, {"message" => msg})
67
+ else
68
+ xml.add_node(root, "error", nil, {"field" => attribute.to_s.camel_case.dcfirst, "message" => msg})
69
+ end
70
+ end
71
+ end
72
+ xml.output(doc)
73
+ end
74
+
75
+ # Add to_json support for datamapper errors too
76
+ def to_json
77
+ @errors.to_json
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,60 @@
1
+ # Adds Capistrano recipes for deploying Flex applications
2
+ #
3
+ # To use these recipes, add the following to your Capfile:
4
+ #
5
+ # require 'restfulx/rails/recipes'
6
+ require 'find'
7
+
8
+ Capistrano::Configuration.instance(:must_exist).load do
9
+ after "deploy:setup", "deploy:flex:setup"
10
+
11
+ namespace :db do
12
+ desc "runs db:refresh in the latest release directory."
13
+ task :refresh, :roles => :db do
14
+ run("cd #{latest_release} && rake db:refresh RAILS_ENV=production")
15
+ end
16
+ end
17
+
18
+ namespace :deploy do
19
+ namespace :flex do
20
+
21
+ desc "Creates the flex_files directory in the shared directory"
22
+ task :setup do
23
+ flex_dir = File.join(shared_path, 'flex_files')
24
+ run "#{try_sudo} mkdir -p #{flex_dir} && #{try_sudo} chmod g+w #{flex_dir}"
25
+ end
26
+
27
+ desc "uploads everything in public/bin up to the server"
28
+ task :via_dumb_copy, :roles => :app do
29
+ # the -p flag on mkdir makes intermediate directories (i.e. both /bin and /bin/history),
30
+ # and doesn't raise an error if any of the directories already exist.
31
+ rails_root = Dir.pwd # You have to run cap tasks from RAILS_ROOT anyways
32
+ base_dir = File.join(rails_root, 'public', 'bin')
33
+ ec2_base_dir = File.join(shared_path, 'flex_files')
34
+
35
+ Find.find(base_dir) do |file|
36
+ filename_without_base_dir = file.sub(base_dir, '')
37
+ if File.directory?(file)
38
+ run "mkdir -p #{File.join(ec2_base_dir, filename_without_base_dir)}"
39
+ else
40
+ content = File.open(file, 'rb') {|f| f.read}
41
+ put content, File.join(ec2_base_dir, filename_without_base_dir)
42
+ end
43
+ end
44
+ end
45
+
46
+ desc "synchronizes the local and remote public/bin directories using rsync"
47
+ task :via_rsync, :roles => :app do
48
+ username = user || ENV['USER']
49
+ rails_root = Dir.pwd # You have to run cap tasks from RAILS_ROOT anyways
50
+ execute_on_servers do |server|
51
+ `rsync -r -p -v -e \"ssh -i #{ssh_options[:keys]}\" #{File.join(rails_root, 'public', 'bin')}/ #{username}@#{server}:#{File.join(shared_path, 'flex_files')}/`
52
+ end
53
+ end
54
+
55
+ task :make_symlink, :roles => :app do
56
+ run "ln -s #{shared_path}/flex_files #{release_path}/public/bin"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,112 @@
1
+ # Used for analyzing your schema and exporting a model.yml file for Rx
2
+ # Provides facilities to convert an existing Rails application schema.rb file to
3
+ # RestfulX model.yml file
4
+ module SchemaToYaml
5
+ # SchemaToYaml.schema_to_yaml
6
+ # - set of commands that introspects your database and formats your model.yml for export
7
+ def self.schema_to_yaml
8
+ # Iterates through your database, and sets up table_arr with all columns
9
+ # - excludes schema_info/schema_migrations/and any other tables you specify in restfulx.yml
10
+ table_arr = ActiveRecord::Base.connection.tables -
11
+ %w(schema_info schema_migrations).map -
12
+ RxSettings.ignored.tables[0].split
13
+
14
+ # Excludes columns from each table
15
+ disregarded_columns = %w(id created_at updated_at) + RxSettings.ignored.fields[0].split
16
+
17
+ # Schema variable is appended to throughout, and is the variable exported to model.yml
18
+ schema = []
19
+
20
+ # Set up empty array for has_many relationships
21
+ @array_of_has_manies = []
22
+
23
+ # Iterates through each table, and checks for any database field ending in _id
24
+ table_arr.each do |table|
25
+ column_arr = ActiveRecord::Base.connection.columns(table)
26
+ column_arr.each do |col|
27
+ col_name = col.name.to_s
28
+ @array_of_has_manies << "#{col_name.gsub(/_id\b/,'')}_#{table}" if col_name[-3,3]=='_id'
29
+ end
30
+ end
31
+
32
+ table_arr.each do |table|
33
+ # Set up empty arrays for other associations
34
+ belong_tos = []
35
+ has_manies = []
36
+ polymorphics = []
37
+
38
+ # Append table name to schema
39
+ # - project:
40
+ schema << "#{table.singularize}:\n"
41
+ column_arr = ActiveRecord::Base.connection.columns(table)
42
+
43
+ column_arr.each do |col|
44
+ col_name = col.name.to_s
45
+
46
+ # Ignore certain columns
47
+ columns_check = []
48
+ disregarded_columns.each {|dc| columns_check << col_name.include?(dc) }
49
+
50
+ # Sets up polymorphics array, we'll need to check for duplicates below
51
+ polymorphics << col_name.gsub('_id','PMCHECK').gsub('_type','PMCHECK')
52
+
53
+ # Appends each column under respective table
54
+ schema << " - #{col_name}: #{col.type}\n" unless columns_check.include?(true)
55
+
56
+ # Checks for certain column names
57
+ # - If it finds parent_id it sets up a tree_model for generation
58
+ # - If it finds _file_size it sets up attachment for generation
59
+ # - Sets up belong_tos
60
+ if col_name == 'parent_id'
61
+ schema << " - tree_model: [#{col_name.gsub(/_id\b/,'')}]\n"
62
+ elsif col_name =~ /_file_size$/
63
+ schema << " - attachment_field: [#{col_name.gsub(/_file_size$/,'')}]\n"
64
+ else
65
+ belong_tos << col_name.gsub(/_id\b/,', ') if col_name[-3,3]=='_id' && !disregarded_columns.include?(col_name)
66
+ end
67
+ end
68
+
69
+ # Checks for duplicates in the polymorphics array (used for error checking)
70
+ if polymorphics.dups.size > 0
71
+ schema << " - polymorphic: [#{polymorphics.dups.first.gsub('PMCHECK','')}]\n"
72
+ @polymorphic = polymorphics.dups.first.gsub('PMCHECK','')
73
+ end
74
+
75
+ # Cleans up has many
76
+ @array_of_has_manies.each do |hm|
77
+ sanity_check = hm.gsub(/^#{table.singularize}_/,'')
78
+ if hm =~ /^#{table.singularize}_/ && table_arr.include?(sanity_check)
79
+ has_manies << hm.gsub(/^#{table.singularize}_/,'') + ', '
80
+ end
81
+ end
82
+
83
+ # Appends belong_to's to schema ##Patch here ## http://gist.github.com/151713 if all of the belongs_to on a particular table are polymorphic, then belong_tos is empty, so belong_tos.last is nil, so 87 (before patch) blows up
84
+ if belong_tos.size > 0
85
+ belong_tos = belong_tos.delete_if {|x| x == "#{@polymorphic}, " }
86
+ if belong_tos.size > 0
87
+ last_in_array_fix = belong_tos.last
88
+ last_in_array_fix = last_in_array_fix.gsub(', ','')
89
+ belong_tos.pop
90
+ belong_tos << last_in_array_fix
91
+ schema << " - belongs_to: [#{belong_tos}]\n"
92
+ end
93
+ end
94
+
95
+ # Appends has_manies' to schema
96
+ if has_manies.size > 0
97
+ last_in_array_fix = has_manies.last
98
+ last_in_array_fix = last_in_array_fix.gsub(', ','')
99
+ has_manies.pop
100
+ has_manies << last_in_array_fix
101
+ schema << " - has_many: [#{has_manies}]\n"
102
+ end
103
+
104
+ schema << "\n"
105
+ end
106
+
107
+ # Writes model.yml file
108
+ yml_file = File.join(RAILS_ROOT, "db", "model.yml")
109
+ File.open(yml_file, "w") { |f| f << schema.to_s }
110
+ puts "Model.yml created at db/model.yml"
111
+ end
112
+ end
@@ -0,0 +1,8 @@
1
+ # Enumerable extensions
2
+ module Enumerable
3
+ # Helps you find duplicates
4
+ # used in schema_to_yaml.rb for cleanup
5
+ def dups
6
+ inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
7
+ end
8
+ end