hyper-mesh 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Gemfile +7 -2
  4. data/README.md +112 -87
  5. data/Rakefile +6 -1
  6. data/docs/action_cable_quickstart.md +20 -16
  7. data/docs/activerecord_api.md +23 -17
  8. data/docs/authorization-policies.md +45 -35
  9. data/docs/client_side_scoping.md +5 -5
  10. data/docs/configuration_details.md +6 -46
  11. data/docs/pusher_faker_quickstart.md +7 -68
  12. data/docs/pusher_quickstart.md +7 -68
  13. data/docs/simple_poller_quickstart.md +6 -67
  14. data/docs/todo-example.md +2 -2
  15. data/docs/word_game.md +3 -1
  16. data/docs/words-example.md +2 -3
  17. data/examples/action-cable/Gemfile +2 -1
  18. data/examples/action-cable/Gemfile.lock +73 -54
  19. data/examples/action-cable/config/initializers/{hyper_mesh.rb → hyperloop.rb} +1 -1
  20. data/examples/action-cable/config/routes.rb +1 -1
  21. data/hyper-mesh.gemspec +10 -4
  22. data/lib/active_record_base.rb +3 -3
  23. data/{examples/action-cable-production-mode/log/.keep → lib/acts_as_string.rb} +0 -0
  24. data/lib/hyper-mesh.rb +11 -19
  25. data/lib/hyper_mesh/version.rb +3 -0
  26. data/lib/hypermesh/version.rb +1 -1
  27. data/lib/reactive_record/active_record/class_methods.rb +10 -3
  28. data/lib/reactive_record/active_record/instance_methods.rb +8 -0
  29. data/lib/reactive_record/active_record/public_columns_hash.rb +8 -2
  30. data/lib/reactive_record/active_record/reactive_record/collection.rb +0 -1
  31. data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +2 -1
  32. data/lib/reactive_record/active_record/reactive_record/isomorphic_base.rb +55 -63
  33. data/lib/reactive_record/active_record/reactive_record/operations.rb +51 -0
  34. data/lib/reactive_record/active_record/reactive_record/reactive_set_relationship_helpers.rb +3 -3
  35. data/lib/reactive_record/active_record/reactive_record/while_loading.rb +93 -84
  36. data/lib/reactive_record/broadcast.rb +183 -0
  37. data/lib/reactive_record/permissions.rb +2 -2
  38. data/reactive_record_test_app/Gemfile +6 -2
  39. data/reactive_record_test_app/Gemfile.lock +120 -60
  40. data/reactive_record_test_app/app/assets/javascripts/application.rb +3 -5
  41. data/reactive_record_test_app/app/assets/javascripts/bigdecimal.rb +1 -0
  42. data/reactive_record_test_app/app/assets/javascripts/reactive_record_config.js +2 -2
  43. data/reactive_record_test_app/app/controllers/application_controller.rb +3 -3
  44. data/reactive_record_test_app/app/controllers/home_controller.rb +1 -1
  45. data/reactive_record_test_app/app/models/models.rb.erb +6 -0
  46. data/reactive_record_test_app/config/application.rb +2 -0
  47. data/reactive_record_test_app/config/environments/development.rb +1 -1
  48. data/reactive_record_test_app/config/routes.rb +1 -2
  49. data/reactive_record_test_app/db/seeds.rb +6 -0
  50. data/reactive_record_test_app/script/rails +0 -0
  51. data/reactive_record_test_app/spec-opal/active-record/rendering_spec.rb +11 -2
  52. data/reactive_record_test_app/spec-opal/active-record/save_spec.rb +3 -4
  53. data/reactive_record_test_app/spec-opal/spec_helper.js.rb +1 -1
  54. data/reactive_record_test_app/spec-opal/test_spec.rb +7 -0
  55. data/reactive_record_test_app/spec_dont_run/README.md +7 -0
  56. data/reactive_record_test_app/{spec-opal/active-record → spec_dont_run/active_record_broken}/permissions_spec.rb +0 -0
  57. data/reactive_record_test_app/{spec-opal/active-record → spec_dont_run/active_record_broken}/prerendering_spec.rb +1 -0
  58. data/spec/{synchromesh/aaa-unit_tests/connection_spec.rb → batch1/aaa-unit_tests/connection_movedspec.rb} +0 -0
  59. data/spec/{synchromesh → batch1}/aaa-unit_tests/dummy_value_spec.rb +2 -2
  60. data/spec/{synchromesh → batch1}/column_types/column_type_spec.rb +2 -2
  61. data/spec/{synchromesh → batch1}/crud_access_regulation/broadcast_controls_access_spec.rb +1 -1
  62. data/spec/{synchromesh → batch1}/crud_access_regulation/model_policies_spec.rb +6 -6
  63. data/spec/batch1/misc/access_like_hash_spec.rb +43 -0
  64. data/spec/batch1/misc/while_loading_spec.rb +196 -0
  65. data/spec/{synchromesh → batch1}/policies/regulate_all_broadcasts_spec.rb +12 -12
  66. data/spec/{synchromesh → batch1}/policies/regulate_broadcast_spec.rb +25 -25
  67. data/spec/{synchromesh/integration → batch2}/authorization_spec.rb +8 -7
  68. data/spec/{synchromesh/integration → batch2}/default_scope_spec.rb +2 -2
  69. data/spec/{synchromesh/integration → batch2}/has_many_through_spec.rb +2 -2
  70. data/spec/{synchromesh/integration → batch2}/relationships_spec.rb +3 -3
  71. data/spec/{reactive_record → batch3}/auto_load_itself_spec.rb +1 -1
  72. data/spec/{reactive_record → batch3}/edge_cases_spec.rb +1 -1
  73. data/spec/{reactive_record → batch3}/finder_method_spec.rb +1 -1
  74. data/spec/{reactive_record → batch3}/many_to_many_spec.rb +2 -2
  75. data/spec/{reactive_record → batch3}/pry_rescue_xspec.rb +0 -0
  76. data/{examples/action-cable-production-mode/public/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css → spec/batch3/readme.txt} +0 -0
  77. data/spec/{reactive_record → batch3}/revert_spec.rb +2 -2
  78. data/spec/{reactive_record → batch3}/save_while_loading_spec.rb +1 -1
  79. data/spec/{reactive_record → batch3}/update_associations_spec.rb +2 -2
  80. data/spec/{reactive_record → batch3}/update_scopes_spec.rb +2 -2
  81. data/spec/{synchromesh/integration → batch4}/saving_during_commit_spec.rb +2 -2
  82. data/spec/{synchromesh/integration → batch4}/scope_spec.rb +30 -2
  83. data/spec/{synchromesh/examples → batch4}/scoped_todos_spec.rb +3 -3
  84. data/spec/{synchromesh/integration → batch4}/synchromesh_spec.rb +2 -2
  85. data/spec/{synchromesh/examples → examples}/dictionary.rb +2 -2
  86. data/spec/{synchromesh/examples → examples}/dictionary_with_client_scopes.rb +2 -2
  87. data/spec/{synchromesh/examples → examples}/random_examples.rb +1 -1
  88. data/spec/{reactive_record/play.rb → play_ground.rb} +0 -0
  89. data/spec/{reactive_record/factory.rb → reactive_record_factory.rb} +0 -0
  90. data/spec/spec_helper.rb +3 -2
  91. data/spec/test_app/Gemfile +8 -3
  92. data/spec/test_app/Gemfile.lock +114 -64
  93. data/spec/test_app/app/views/components.rb +1 -2
  94. data/spec/test_app/config/application.rb +2 -0
  95. data/spec/test_app/config/routes.rb +1 -1
  96. data/spec/{synchromesh/integration/test_components.rb → test_components.rb} +0 -0
  97. metadata +144 -137
  98. data/app/controllers/reactive_record/application_controller.rb +0 -4
  99. data/app/controllers/reactive_record/reactive_record_controller.rb +0 -49
  100. data/config/routes.rb +0 -7
  101. data/examples/action-cable-production-mode/public/assets/application-90043e04e9e784054fd08159fa7aafe5e23d3ffb31584b1bea1e47043c9cfb5a.js +0 -50
  102. data/examples/action-cable-production-mode/public/assets/application-90043e04e9e784054fd08159fa7aafe5e23d3ffb31584b1bea1e47043c9cfb5a.js.gz +0 -0
  103. data/examples/action-cable-production-mode/public/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css.gz +0 -0
  104. data/examples/action-cable-production-mode/tmp/.keep +0 -0
  105. data/examples/action-cable/log/.keep +0 -0
  106. data/examples/action-cable/tmp/.keep +0 -0
  107. data/examples/pusher-fake/log/.keep +0 -0
  108. data/examples/pusher-fake/tmp/.keep +0 -0
  109. data/examples/pusher/log/.keep +0 -0
  110. data/examples/pusher/tmp/.keep +0 -0
  111. data/examples/simple-poller/log/.keep +0 -0
  112. data/examples/simple-poller/tmp/.keep +0 -0
  113. data/examples/word-game/log/.keep +0 -0
  114. data/examples/word-game/tmp/.keep +0 -0
  115. data/examples/words/log/.keep +0 -0
  116. data/examples/words/tmp/.keep +0 -0
  117. data/lib/reactive_record/version.rb +0 -3
  118. data/lib/sources/hyper-mesh/pusher.js +0 -98
  119. data/lib/synchromesh/action_cable.rb +0 -39
  120. data/lib/synchromesh/client_drivers.rb +0 -357
  121. data/lib/synchromesh/configuration.rb +0 -40
  122. data/lib/synchromesh/connection.rb +0 -170
  123. data/lib/synchromesh/policy.rb +0 -504
  124. data/lib/synchromesh/synchromesh.rb +0 -159
  125. data/lib/synchromesh/synchromesh_controller.rb +0 -162
  126. data/reactive_record_test_app/README.rdoc +0 -261
  127. data/reactive_record_test_app/app/assets/javascripts/components/another_component.rb +0 -24
  128. data/reactive_record_test_app/app/assets/javascripts/components/empty_component.rb +0 -6
  129. data/reactive_record_test_app/app/assets/javascripts/components/todo_item_component.js.rb +0 -16
  130. data/reactive_record_test_app/app/assets/javascripts/components/todos_component.js.rb +0 -42
  131. data/reactive_record_test_app/app/assets/javascripts/components/todos_main_component.rb +0 -49
  132. data/reactive_record_test_app/app/assets/javascripts/react_js_test_only.js +0 -21618
  133. data/reactive_record_test_app/app/assets/javascripts/spec/reactive_record_xspec.js.rb +0 -42
  134. data/reactive_record_test_app/app/controllers/test_controller.rb +0 -7
  135. data/reactive_record_test_app/app/mailers/.gitkeep +0 -0
  136. data/reactive_record_test_app/app/models/models.rb +0 -1
  137. data/reactive_record_test_app/app/policies/application_policy.rb +0 -5
  138. data/reactive_record_test_app/app/views/components.rb +0 -4
  139. data/reactive_record_test_app/app/views/components/test.rb +0 -18
  140. data/reactive_record_test_app/app/views/home/index.html.erb +0 -1
  141. data/reactive_record_test_app/app/views/layouts/application.html.erb +0 -17
  142. data/reactive_record_test_app/config/environments/production.rb +0 -70
  143. data/reactive_record_test_app/config/environments/test.rb +0 -41
  144. data/spec/synchromesh/integration/transports_spec.rb +0 -308
  145. data/spec/synchromesh/policies/auto_connect_spec.rb +0 -60
  146. data/spec/synchromesh/policies/auto_loader_spec.rb +0 -34
  147. data/spec/synchromesh/policies/policy_methods_spec.rb +0 -85
  148. data/spec/synchromesh/policies/regulate_class_connection_spec.rb +0 -50
  149. data/spec/synchromesh/policies/regulate_instance_connection_spec.rb +0 -66
  150. data/spec/test_app/log/.keep +0 -0
@@ -1,159 +0,0 @@
1
- require 'synchromesh/configuration'
2
- # Provides the configuration and the two basic routines for the server
3
- # to indicate that records have changed: after_change and after_destroy
4
- module HyperMesh
5
-
6
- extend Configuration
7
-
8
- def self.initialize_policies
9
- config_reset unless @config_reset_called
10
- end
11
-
12
- def self.config_reset
13
- @config_reset_called = true
14
- Object.send(:remove_const, :Application) if @fake_application_defined
15
- policy = begin
16
- Object.const_get 'ApplicationPolicy'
17
- rescue Exception => e
18
- #raise e unless e.is_a?(NameError) && e.message == "uninitialized constant ApplicationPolicy"
19
- rescue LoadError
20
- end
21
- application = begin
22
- Object.const_get('Application')
23
- rescue LoadError
24
- rescue Exception => e
25
- #raise e unless e.is_a?(NameError) && e.message == "uninitialized constant Application"
26
- end if policy
27
- if policy && !application
28
- Object.const_set 'Application', Class.new
29
- @fake_application_defined = true
30
- end
31
- @pusher = nil
32
- Connection.build_tables
33
- end
34
-
35
- define_setting(:transport, :none) do |transport|
36
- if transport == :action_cable
37
- require 'synchromesh/action_cable'
38
- opts[:refresh_channels_every] = :never
39
- else
40
- require 'pusher' if transport == :pusher
41
- opts[:refresh_channels_every] = nil if opts[:refresh_channels_every] == :never
42
- end
43
- end
44
-
45
- define_setting :opts, {}
46
- define_setting :channel_prefix
47
- define_setting :client_logging, true
48
-
49
- def self.app_id
50
- opts[:app_id] || Pusher.app_id if transport == :pusher
51
- end
52
-
53
- def self.key
54
- opts[:key] || Pusher.key if transport == :pusher
55
- end
56
-
57
- def self.secret
58
- opts[:secret] || Pusher.secret if transport == :pusher
59
- end
60
-
61
- def self.encrypted
62
- opts.key?(:encrypted) ? opts[:encrypted] : true
63
- end
64
-
65
- def self.expire_polled_connection_in
66
- opts[:expire_polled_connection_in] || (5 * 60)
67
- end
68
-
69
- def self.seconds_between_poll
70
- opts[:seconds_between_poll] || 0.5
71
- end
72
-
73
- def self.expire_new_connection_in
74
- opts[:expire_new_connection_in] || 10.seconds
75
- end
76
-
77
- def self.refresh_channels_timeout
78
- opts[:refresh_channels_timeout] || 5.seconds
79
- end
80
-
81
- def self.refresh_channels_every
82
- opts[:refresh_channels_every] || 2.minutes
83
- end
84
-
85
- def self.refresh_channels
86
- new_channels = pusher.channels[:channels].collect do |channel|
87
- channel.gsub(/^#{Regexp.quote(HyperMesh.channel)}/,'')
88
- end
89
- end
90
-
91
- def self.send(channel, data)
92
- if !on_server?
93
- send_to_server(channel, data)
94
- elsif transport == :pusher
95
- pusher.trigger("#{HyperMesh.channel}-#{data[1][:channel]}", *data)
96
- elsif transport == :action_cable
97
- ActionCable.server.broadcast("synchromesh-#{channel}", message: data[0], data: data[1])
98
- end
99
- end
100
-
101
- def self.on_server?
102
- Rails.const_defined? 'Server'
103
- end
104
-
105
- def self.send_to_server(channel, data)
106
- salt = SecureRandom.hex
107
- authorization = HyperMesh.authorization(salt, channel, data[1][:broadcast_id])
108
- raise 'no server running' unless Connection.root_path
109
- uri = URI("#{Connection.root_path}console_update")
110
- http = Net::HTTP.new(uri.host, uri.port)
111
- request = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
112
- if uri.scheme == 'https'
113
- http.use_ssl = true
114
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
115
- end
116
- request.body = {
117
- channel: channel, data: data, salt: salt, authorization: authorization
118
- }.to_json
119
- http.request(request)
120
- end
121
-
122
- def self.pusher
123
- unless @pusher
124
- unless channel_prefix
125
- self.transport = nil
126
- raise '******** NO CHANNEL PREFIX SET ***************'
127
- end
128
- @pusher = Pusher::Client.new(
129
- opts || { app_id: app_id, key: key, secret: secret }
130
- )
131
- end
132
- @pusher
133
- end
134
-
135
- def self.channel
136
- "private-#{channel_prefix}"
137
- end
138
-
139
- def self.authorization(salt, channel, session_id)
140
- secret_key = Rails.application.secrets[:secret_key_base]
141
- Digest::SHA1.hexdigest(
142
- "salt: #{salt}, channel: #{channel}, session_id: #{session_id}, secret_key: #{secret_key}"
143
- )
144
- end
145
-
146
- def self.after_commit(operation, model)
147
- InternalPolicy.regulate_broadcast(model) do |data|
148
- if !HyperMesh.on_server? && Connection.root_path
149
- HyperMesh.send_to_server(data[:channel], [operation, data])
150
- else
151
- Connection.send_to_channel(data[:channel], [operation, data])
152
- end
153
- end
154
- rescue Exception
155
- nil # this is because during db migration we have problems... should investigate more...
156
- end
157
-
158
- Connection.transport = self
159
- end
@@ -1,162 +0,0 @@
1
- module ReactiveRecord
2
- ::HyperMesh::Engine.routes.append do
3
- HyperMesh.initialize_policies
4
-
5
- module ::WebConsole
6
- class Middleware
7
- private
8
- def acceptable_content_type?(headers)
9
- Mime::Type.parse(headers['Content-Type'] || '').first == Mime[:html]
10
- end
11
- end
12
- end if defined? ::WebConsole::Middleware
13
-
14
- module ::Rails
15
- module Rack
16
- class Logger < ActiveSupport::LogSubscriber
17
- unless method_defined? :pre_synchromesh_call
18
- alias pre_synchromesh_call call
19
- def call(env)
20
- if !HyperMesh.opts[:noisy] && env['HTTP_X_SYNCHROMESH_SILENT_REQUEST']
21
- Rails.logger.silence do
22
- pre_synchromesh_call(env)
23
- end
24
- else
25
- pre_synchromesh_call(env)
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end if defined?(::Rails::Rack::Logger)
32
-
33
- class HyperMeshController < ::ApplicationController
34
-
35
- protect_from_forgery except: [:console_update]
36
-
37
- def client_id
38
- params[:client_id]
39
- end
40
-
41
- before_action do
42
- session.delete 'synchromesh-dummy-init' unless session.id
43
- end
44
-
45
- def channels(user = acting_user, session_id = session.id)
46
- HyperMesh::AutoConnect.channels(session_id, user)
47
- end
48
-
49
- def can_connect?(channel, user = acting_user)
50
- HyperMesh::InternalPolicy.regulate_connection(
51
- user,
52
- HyperMesh::InternalPolicy.channel_to_string(channel)
53
- )
54
- true
55
- rescue
56
- nil
57
- end
58
-
59
- def view_permitted?(model, attr, user = acting_user)
60
- !!model.check_permission_with_acting_user(user, :view_permitted?, attr)
61
- rescue
62
- nil
63
- end
64
-
65
- def viewable_attributes(model, user = acting_user)
66
- model.attributes.select { |attr| view_permitted?(model, attr, user) }
67
- end
68
-
69
- [:create, :update, :destroy].each do |op|
70
- define_method "#{op}_permitted?" do |model, user = acting_user|
71
- begin
72
- !!model.check_permission_with_acting_user(user, "#{op}_permitted?".to_sym)
73
- rescue
74
- nil
75
- end
76
- end
77
- end
78
-
79
- def debug_console
80
- if Rails.env.development?
81
- render inline: "<style>div#console {height: 100% !important;}</style>\n".html_safe
82
- # "<div>additional helper methods: channels, can_connect? "\
83
- # "viewable_attributes, view_permitted?, create_permitted?, "\
84
- # "update_permitted? and destroy_permitted?</div>\n".html_safe
85
- console
86
- else
87
- head :unauthorized
88
- end
89
- end
90
-
91
- def subscribe
92
- HyperMesh::InternalPolicy.regulate_connection(try(:acting_user), params[:channel])
93
- root_path = request.original_url.gsub(/synchromesh-subscribe.*$/, '')
94
- HyperMesh::Connection.open(params[:channel], client_id, root_path)
95
- head :ok
96
- rescue Exception
97
- head :unauthorized
98
- end
99
-
100
- def read
101
- root_path = request.original_url.gsub(/synchromesh-read.*$/, '')
102
- data = HyperMesh::Connection.read(client_id, root_path)
103
- render json: data
104
- end
105
-
106
- def pusher_auth
107
- channel = params[:channel_name].gsub(/^#{Regexp.quote(HyperMesh.channel)}\-/,'')
108
- HyperMesh::InternalPolicy.regulate_connection(acting_user, channel)
109
- response = HyperMesh.pusher.authenticate(params[:channel_name], params[:socket_id])
110
- render json: response
111
- rescue Exception => e
112
- head :unauthorized
113
- end
114
-
115
- def action_cable_auth
116
- channel = params[:channel_name].gsub(/^#{Regexp.quote(HyperMesh.channel)}\-/,'')
117
- HyperMesh::InternalPolicy.regulate_connection(acting_user, channel)
118
- salt = SecureRandom.hex
119
- authorization = HyperMesh.authorization(salt, channel, client_id)
120
- render json: {authorization: authorization, salt: salt}
121
- rescue Exception
122
- head :unauthorized
123
- end
124
-
125
- def connect_to_transport
126
- root_path = request.original_url.gsub(/synchromesh-connect-to-transport.*$/, '')
127
- render json: HyperMesh::Connection.connect_to_transport(params[:channel], client_id, root_path)
128
- end
129
-
130
- def console_update
131
- authorization = HyperMesh.authorization(params[:salt], params[:channel], params[:data][1][:broadcast_id]) #params[:data].to_json)
132
- return head :unauthorized if authorization != params[:authorization]
133
- HyperMesh::Connection.send_to_channel(params[:channel], params[:data])
134
- head :no_content
135
- rescue
136
- head :unauthorized
137
- end
138
-
139
- def server_up
140
- head :no_content
141
- end
142
-
143
- end unless defined? HyperMeshController
144
-
145
- match 'synchromesh-subscribe/:client_id/:channel',
146
- to: 'hyper_mesh#subscribe', via: :get
147
- match 'synchromesh-read/:client_id',
148
- to: 'hyper_mesh#read', via: :get
149
- match 'synchromesh-pusher-auth',
150
- to: 'hyper_mesh#pusher_auth', via: :post
151
- match 'synchromesh-action-cable-auth/:client_id/:channel_name',
152
- to: 'hyper_mesh#action_cable_auth', via: :post
153
- match 'synchromesh-connect-to-transport/:client_id/:channel',
154
- to: 'hyper_mesh#connect_to_transport', via: :get
155
- match 'console',
156
- to: 'hyper_mesh#debug_console', via: :get
157
- match 'console_update',
158
- to: 'hyper_mesh#console_update', via: :post
159
- match 'server_up',
160
- to: 'hyper_mesh#server_up', via: :get
161
- end
162
- end
@@ -1,261 +0,0 @@
1
- == Welcome to Rails
2
-
3
- Rails is a web-application framework that includes everything needed to create
4
- database-backed web applications according to the Model-View-Control pattern.
5
-
6
- This pattern splits the view (also called the presentation) into "dumb"
7
- templates that are primarily responsible for inserting pre-built data in between
8
- HTML tags. The model contains the "smart" domain objects (such as Account,
9
- Product, Person, Post) that holds all the business logic and knows how to
10
- persist themselves to a database. The controller handles the incoming requests
11
- (such as Save New Account, Update Product, Show Post) by manipulating the model
12
- and directing data to the view.
13
-
14
- In Rails, the model is handled by what's called an object-relational mapping
15
- layer entitled Active Record. This layer allows you to present the data from
16
- database rows as objects and embellish these data objects with business logic
17
- methods. You can read more about Active Record in
18
- link:files/vendor/rails/activerecord/README.html.
19
-
20
- The controller and view are handled by the Action Pack, which handles both
21
- layers by its two parts: Action View and Action Controller. These two layers
22
- are bundled in a single package due to their heavy interdependence. This is
23
- unlike the relationship between the Active Record and Action Pack that is much
24
- more separate. Each of these packages can be used independently outside of
25
- Rails. You can read more about Action Pack in
26
- link:files/vendor/rails/actionpack/README.html.
27
-
28
-
29
- == Getting Started
30
-
31
- 1. At the command prompt, create a new Rails application:
32
- <tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
33
-
34
- 2. Change directory to <tt>myapp</tt> and start the web server:
35
- <tt>cd myapp; rails server</tt> (run with --help for options)
36
-
37
- 3. Go to http://localhost:3000/ and you'll see:
38
- "Welcome aboard: You're riding Ruby on Rails!"
39
-
40
- 4. Follow the guidelines to start developing your application. You can find
41
- the following resources handy:
42
-
43
- * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
44
- * Ruby on Rails Tutorial Book: http://www.railstutorial.org/
45
-
46
-
47
- == Debugging Rails
48
-
49
- Sometimes your application goes wrong. Fortunately there are a lot of tools that
50
- will help you debug it and get it back on the rails.
51
-
52
- First area to check is the application log files. Have "tail -f" commands
53
- running on the server.log and development.log. Rails will automatically display
54
- debugging and runtime information to these files. Debugging info will also be
55
- shown in the browser on requests from 127.0.0.1.
56
-
57
- You can also log your own messages directly into the log file from your code
58
- using the Ruby logger class from inside your controllers. Example:
59
-
60
- class WeblogController < ActionController::Base
61
- def destroy
62
- @weblog = Weblog.find(params[:id])
63
- @weblog.destroy
64
- logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
65
- end
66
- end
67
-
68
- The result will be a message in your log file along the lines of:
69
-
70
- Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
71
-
72
- More information on how to use the logger is at http://www.ruby-doc.org/core/
73
-
74
- Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
75
- several books available online as well:
76
-
77
- * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
78
- * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
79
-
80
- These two books will bring you up to speed on the Ruby language and also on
81
- programming in general.
82
-
83
-
84
- == Debugger
85
-
86
- Debugger support is available through the debugger command when you start your
87
- Mongrel or WEBrick server with --debugger. This means that you can break out of
88
- execution at any point in the code, investigate and change the model, and then,
89
- resume execution! You need to install ruby-debug to run the server in debugging
90
- mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
91
-
92
- class WeblogController < ActionController::Base
93
- def index
94
- @posts = Post.all
95
- debugger
96
- end
97
- end
98
-
99
- So the controller will accept the action, run the first line, then present you
100
- with a IRB prompt in the server window. Here you can do things like:
101
-
102
- >> @posts.inspect
103
- => "[#<Post:0x14a6be8
104
- @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
105
- #<Post:0x14a6620
106
- @attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
107
- >> @posts.first.title = "hello from a debugger"
108
- => "hello from a debugger"
109
-
110
- ...and even better, you can examine how your runtime objects actually work:
111
-
112
- >> f = @posts.first
113
- => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
114
- >> f.
115
- Display all 152 possibilities? (y or n)
116
-
117
- Finally, when you're ready to resume execution, you can enter "cont".
118
-
119
-
120
- == Console
121
-
122
- The console is a Ruby shell, which allows you to interact with your
123
- application's domain model. Here you'll have all parts of the application
124
- configured, just like it is when the application is running. You can inspect
125
- domain models, change values, and save to the database. Starting the script
126
- without arguments will launch it in the development environment.
127
-
128
- To start the console, run <tt>rails console</tt> from the application
129
- directory.
130
-
131
- Options:
132
-
133
- * Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
134
- made to the database.
135
- * Passing an environment name as an argument will load the corresponding
136
- environment. Example: <tt>rails console production</tt>.
137
-
138
- To reload your controllers and models after launching the console run
139
- <tt>reload!</tt>
140
-
141
- More information about irb can be found at:
142
- link:http://www.rubycentral.org/pickaxe/irb.html
143
-
144
-
145
- == dbconsole
146
-
147
- You can go to the command line of your database directly through <tt>rails
148
- dbconsole</tt>. You would be connected to the database with the credentials
149
- defined in database.yml. Starting the script without arguments will connect you
150
- to the development database. Passing an argument will connect you to a different
151
- database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
152
- PostgreSQL and SQLite 3.
153
-
154
- == Description of Contents
155
-
156
- The default directory structure of a generated Ruby on Rails application:
157
-
158
- |-- app
159
- | |-- assets
160
- | | |-- images
161
- | | |-- javascripts
162
- | | `-- stylesheets
163
- | |-- controllers
164
- | |-- helpers
165
- | |-- mailers
166
- | |-- models
167
- | `-- views
168
- | `-- layouts
169
- |-- config
170
- | |-- environments
171
- | |-- initializers
172
- | `-- locales
173
- |-- db
174
- |-- doc
175
- |-- lib
176
- | |-- assets
177
- | `-- tasks
178
- |-- log
179
- |-- public
180
- |-- script
181
- |-- test
182
- | |-- fixtures
183
- | |-- functional
184
- | |-- integration
185
- | |-- performance
186
- | `-- unit
187
- |-- tmp
188
- | `-- cache
189
- | `-- assets
190
- `-- vendor
191
- |-- assets
192
- | |-- javascripts
193
- | `-- stylesheets
194
- `-- plugins
195
-
196
- app
197
- Holds all the code that's specific to this particular application.
198
-
199
- app/assets
200
- Contains subdirectories for images, stylesheets, and JavaScript files.
201
-
202
- app/controllers
203
- Holds controllers that should be named like weblogs_controller.rb for
204
- automated URL mapping. All controllers should descend from
205
- ApplicationController which itself descends from ActionController::Base.
206
-
207
- app/models
208
- Holds models that should be named like post.rb. Models descend from
209
- ActiveRecord::Base by default.
210
-
211
- app/views
212
- Holds the template files for the view that should be named like
213
- weblogs/index.html.erb for the WeblogsController#index action. All views use
214
- eRuby syntax by default.
215
-
216
- app/views/layouts
217
- Holds the template files for layouts to be used with views. This models the
218
- common header/footer method of wrapping views. In your views, define a layout
219
- using the <tt>layout :default</tt> and create a file named default.html.erb.
220
- Inside default.html.erb, call <% yield %> to render the view using this
221
- layout.
222
-
223
- app/helpers
224
- Holds view helpers that should be named like weblogs_helper.rb. These are
225
- generated for you automatically when using generators for controllers.
226
- Helpers can be used to wrap functionality for your views into methods.
227
-
228
- config
229
- Configuration files for the Rails environment, the routing map, the database,
230
- and other dependencies.
231
-
232
- db
233
- Contains the database schema in schema.rb. db/migrate contains all the
234
- sequence of Migrations for your schema.
235
-
236
- doc
237
- This directory is where your application documentation will be stored when
238
- generated using <tt>rake doc:app</tt>
239
-
240
- lib
241
- Application specific libraries. Basically, any kind of custom code that
242
- doesn't belong under controllers, models, or helpers. This directory is in
243
- the load path.
244
-
245
- public
246
- The directory available for the web server. Also contains the dispatchers and the
247
- default HTML files. This should be set as the DOCUMENT_ROOT of your web
248
- server.
249
-
250
- script
251
- Helper scripts for automation and generation.
252
-
253
- test
254
- Unit and functional tests along with fixtures. When using the rails generate
255
- command, template test files will be generated for you and placed in this
256
- directory.
257
-
258
- vendor
259
- External libraries that the application depends on. Also includes the plugins
260
- subdirectory. If the app has frozen rails, those gems also go here, under
261
- vendor/rails/. This directory is in the load path.