dyoder-waves 0.7.3 → 0.7.6
Sign up to get free protection for your applications and to get access to all the features.
- data/app/bin/waves-console +1 -0
- data/app/bin/waves-server +1 -0
- data/app/configurations/development.rb.erb +5 -6
- data/app/configurations/mapping.rb.erb +1 -2
- data/app/configurations/production.rb.erb +2 -2
- data/app/controllers/.gitignore +0 -0
- data/app/doc/.gitignore +0 -0
- data/app/helpers/.gitignore +0 -0
- data/app/lib/application.rb.erb +4 -2
- data/app/lib/tasks/.gitignore +0 -0
- data/app/log/.gitignore +0 -0
- data/app/models/.gitignore +0 -0
- data/app/public/css/.gitignore +0 -0
- data/app/public/flash/.gitignore +0 -0
- data/app/public/images/.gitignore +0 -0
- data/app/public/javascript/.gitignore +0 -0
- data/app/schema/migrations/.gitignore +0 -0
- data/app/tmp/sessions/.gitignore +0 -0
- data/app/views/.gitignore +0 -0
- data/bin/waves +29 -46
- data/bin/waves-console +1 -1
- data/bin/waves-server +1 -1
- data/lib/commands/waves-console.rb +0 -3
- data/lib/controllers/base.rb +11 -0
- data/lib/controllers/mixin.rb +39 -32
- data/lib/dispatchers/base.rb +37 -22
- data/lib/dispatchers/default.rb +25 -11
- data/lib/foundations/default.rb +6 -8
- data/lib/foundations/simple.rb +13 -0
- data/lib/helpers/asset_helper.rb +67 -0
- data/lib/helpers/common.rb +4 -0
- data/lib/helpers/default.rb +13 -0
- data/lib/helpers/form.rb +1 -0
- data/lib/helpers/number_helper.rb +25 -0
- data/lib/helpers/tag_helper.rb +58 -0
- data/lib/helpers/url_helper.rb +77 -0
- data/lib/layers/default_errors.rb +7 -5
- data/lib/layers/mvc.rb +54 -0
- data/lib/layers/orm/active_record.rb +93 -0
- data/lib/layers/orm/active_record/migrations/empty.rb.erb +9 -0
- data/lib/layers/orm/active_record/tasks/generate.rb +28 -0
- data/lib/layers/orm/active_record/tasks/schema.rb +22 -0
- data/lib/layers/orm/data_mapper.rb +38 -0
- data/lib/layers/orm/filebase.rb +22 -0
- data/lib/layers/orm/migration.rb +79 -0
- data/lib/layers/orm/sequel.rb +86 -0
- data/lib/layers/orm/sequel/migrations/empty.rb.erb +9 -0
- data/lib/layers/orm/sequel/tasks/generate.rb +28 -0
- data/lib/layers/orm/sequel/tasks/schema.rb +16 -0
- data/lib/layers/simple.rb +35 -0
- data/lib/layers/simple_errors.rb +11 -5
- data/lib/mapping/mapping.rb +61 -24
- data/lib/mapping/pretty_urls.rb +5 -3
- data/lib/renderers/erubis.rb +3 -1
- data/lib/renderers/mixin.rb +1 -4
- data/lib/runtime/application.rb +12 -8
- data/lib/runtime/blackboard.rb +57 -0
- data/lib/runtime/configuration.rb +60 -55
- data/lib/runtime/logger.rb +8 -1
- data/lib/runtime/request.rb +5 -4
- data/lib/runtime/response.rb +3 -3
- data/lib/runtime/response_mixin.rb +3 -0
- data/lib/runtime/response_proxy.rb +4 -1
- data/lib/runtime/server.rb +18 -5
- data/lib/runtime/session.rb +20 -10
- data/lib/tasks/cluster.rb +2 -1
- data/lib/tasks/generate.rb +76 -11
- data/lib/utilities/hash.rb +31 -0
- data/lib/utilities/inflect.rb +86 -170
- data/lib/utilities/inflect/english.rb +84 -0
- data/lib/utilities/integer.rb +23 -16
- data/lib/utilities/module.rb +19 -15
- data/lib/utilities/object.rb +22 -14
- data/lib/utilities/proc.rb +13 -6
- data/lib/utilities/string.rb +58 -44
- data/lib/utilities/symbol.rb +4 -1
- data/lib/views/base.rb +9 -0
- data/lib/views/mixin.rb +3 -1
- data/lib/waves.rb +15 -13
- metadata +50 -25
- data/lib/utilities/kernel.rb +0 -34
- data/lib/verify/mapping.rb +0 -29
- data/lib/verify/request.rb +0 -40
data/lib/foundations/default.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
require 'layers/orm/sequel'
|
2
1
|
module Waves
|
3
2
|
module Foundations
|
3
|
+
# The Default foundation supports the common MVC development pattern, a la Rails and Merb. Models, controllers, views, templates, and helpers live in the corresponding directories. When your code calls for a specific M, V, C, or H, Waves tries to load it from a file matching the snake-case of the constant name. If the file does not exist, Waves creates the constant from a sensible (and customizable) default.
|
4
|
+
#
|
5
|
+
# This foundation does not include any ORM configuration. You can include Waves::Layers::ORM::Sequel or custom configure your model.
|
6
|
+
|
7
|
+
|
4
8
|
module Default
|
5
9
|
|
6
10
|
def self.included( app )
|
@@ -8,14 +12,8 @@ module Waves
|
|
8
12
|
app.instance_eval do
|
9
13
|
|
10
14
|
include Waves::Layers::Simple
|
15
|
+
include Waves::Layers::MVC
|
11
16
|
include Waves::Layers::DefaultErrors
|
12
|
-
include Waves::Layers::MVC
|
13
|
-
include Waves::Layers::ORM::Sequel
|
14
|
-
|
15
|
-
# Set autoloading from default.rb files
|
16
|
-
#autoinit :Configurations do
|
17
|
-
# autoload_class true
|
18
|
-
#end
|
19
17
|
|
20
18
|
end
|
21
19
|
|
data/lib/foundations/simple.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
1
|
module Waves
|
2
|
+
|
3
|
+
# A Waves Foundation provides enough functionality to allow a Waves application
|
4
|
+
# to run. At the bare minimum, this means creating configuration classes in the Configurations
|
5
|
+
# namespace, as is done in the Simple foundation
|
6
|
+
#
|
7
|
+
# Typically, a Foundation will include several Layers, perform any necessary
|
8
|
+
# configuration, and register the application with the Waves module
|
2
9
|
module Foundations
|
3
10
|
|
11
|
+
# The Simple foundation provides the bare minimum needed to run a Waves application.
|
12
|
+
# It is intended for use as the basis of more fully-featured foundations, but you can
|
13
|
+
# use it as a standalone where all the request processing is done directly in a
|
14
|
+
# mapping lambda.
|
4
15
|
module Simple
|
5
16
|
|
17
|
+
# On inclusion in a module, the Simple foundation includes Waves::Layers::Simple and
|
18
|
+
# registers the module as a Waves application.
|
6
19
|
def self.included( app )
|
7
20
|
|
8
21
|
app.instance_eval do
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Waves
|
2
|
+
module Helpers
|
3
|
+
module AssetHelper
|
4
|
+
# Returns an html image tag for the +source+. The +source+ can be a full
|
5
|
+
# path or a file that exists in your public images directory. Note that
|
6
|
+
# specifying a filename without the extension is now deprecated in Rails.
|
7
|
+
# You can add html attributes using the +options+. The +options+ supports
|
8
|
+
# two additional keys for convienence and conformance:
|
9
|
+
#
|
10
|
+
# * <tt>:alt</tt> - If no alt text is given, the file name part of the
|
11
|
+
# +source+ is used (capitalized and without the extension)
|
12
|
+
# * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
|
13
|
+
# width="30" and height="45". <tt>:size</tt> will be ignored if the
|
14
|
+
# value is not in the correct format.
|
15
|
+
#
|
16
|
+
# image_tag("icon.png") # =>
|
17
|
+
# <img src="/images/icon.png" alt="Icon" />
|
18
|
+
# image_tag("icon.png", :size => "16x10", :alt => "Edit Entry") # =>
|
19
|
+
# <img src="/images/icon.png" width="16" height="10" alt="Edit Entry" />
|
20
|
+
# image_tag("/icons/icon.gif", :size => "16x16") # =>
|
21
|
+
# <img src="/icons/icon.gif" width="16" height="16" alt="Icon" />
|
22
|
+
def image_tag(source, options = {})
|
23
|
+
options.symbolize_keys!
|
24
|
+
|
25
|
+
options[:src] = image_path(source)
|
26
|
+
options[:alt] ||= File.basename(options[:src], '.*').split('.').first.capitalize
|
27
|
+
|
28
|
+
if options[:size]
|
29
|
+
options[:width], options[:height] = options[:size].split("x") if options[:size] =~ %r{^\d+x\d+$}
|
30
|
+
options.delete(:size)
|
31
|
+
end
|
32
|
+
|
33
|
+
tag("img", options)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Computes the path to an image asset in the public images directory.
|
37
|
+
# Full paths from the document root will be passed through.
|
38
|
+
# Used internally by image_tag to build the image path. Passing
|
39
|
+
# a filename without an extension is deprecated.
|
40
|
+
#
|
41
|
+
# image_path("edit.png") # => /images/edit.png
|
42
|
+
# image_path("icons/edit.png") # => /images/icons/edit.png
|
43
|
+
# image_path("/icons/edit.png") # => /icons/edit.png
|
44
|
+
def image_path(source)
|
45
|
+
compute_public_path(source, 'images', 'png')
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def compute_public_path(source, dir, ext)
|
50
|
+
source = source.dup
|
51
|
+
source << ".#{ext}" if File.extname(source).blank?
|
52
|
+
unless source =~ %r{^[-a-z]+://}
|
53
|
+
source = "/#{dir}/#{source}" unless source[0] == ?/
|
54
|
+
asset_id = rails_asset_id(source)
|
55
|
+
source << '?' + asset_id if defined?(RAILS_ROOT) && !asset_id.blank?
|
56
|
+
# source = "#{ActionController::Base.asset_host}#{@controller.request.relative_url_root}#{source}"
|
57
|
+
end
|
58
|
+
source
|
59
|
+
end
|
60
|
+
|
61
|
+
def rails_asset_id(source)
|
62
|
+
ENV["WAVES_ASSET_ID"] || File.mtime("public/#{source}").to_i.to_s rescue ""
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/helpers/common.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
module Waves
|
2
|
+
|
3
|
+
# Helper methods can be defined for any view template by simply defining them within the default Helper module in <tt>helpers/default.rb</tt> of the generated application. Helpers specific to a particular View class can be explicitly defined by creating a helper module that corresponds to the View class. For examples, for the +User+ View class, you would define a helper module in <tt>user.rb</tt> named +User+.
|
4
|
+
#
|
5
|
+
# The default helper class initially includes a wide-variety of helpers, including helpers for layouts, Textile formatting, rendering forms, and nested views, as well as helpers for accessing the request and response objects. More helpers will be added in future releases, but in many cases, there is no need to include all of them in your application.
|
2
6
|
module Helpers
|
3
7
|
|
4
8
|
# Common helpers are helpers that are needed for just about any Web page. For example,
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Waves
|
2
|
+
module Helpers
|
3
|
+
module Default
|
4
|
+
attr_reader :request, :content
|
5
|
+
include Waves::ResponseMixin
|
6
|
+
include Waves::Helpers::Common
|
7
|
+
include Waves::Helpers::Formatting
|
8
|
+
include Waves::Helpers::Model
|
9
|
+
include Waves::Helpers::View
|
10
|
+
include Waves::Helpers::Form
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/helpers/form.rb
CHANGED
@@ -15,6 +15,7 @@ module Waves
|
|
15
15
|
# will invoke the +text+ form view (the template in +templates/form/text.mab+),
|
16
16
|
# passing in the name ('blog.title') and the value (@blog.title) as instance variables.
|
17
17
|
#
|
18
|
+
# These helpers are Markaby only.
|
18
19
|
module Form
|
19
20
|
|
20
21
|
# This method really is a place-holder for common wrappers around groups of
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Waves
|
2
|
+
module Helpers
|
3
|
+
module NumberHelper
|
4
|
+
|
5
|
+
# Formats a +number+ with grouped thousands using +delimiter+. You
|
6
|
+
# can customize the format in the +options+ hash.
|
7
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter, defaults to ","
|
8
|
+
# * <tt>:separator</tt> - Sets the separator between the units, defaults to "."
|
9
|
+
#
|
10
|
+
# number_with_delimiter(12345678) => 12,345,678
|
11
|
+
# number_with_delimiter(12345678.05) => 12,345,678.05
|
12
|
+
# number_with_delimiter(12345678, :delimiter => ".") => 12.345.678
|
13
|
+
def number_with_delimiter(number, delimiter=",", separator=".")
|
14
|
+
begin
|
15
|
+
parts = number.to_s.split(separator)
|
16
|
+
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
17
|
+
parts.join separator
|
18
|
+
rescue
|
19
|
+
number
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Waves
|
2
|
+
module Helpers
|
3
|
+
module TagHelper
|
4
|
+
|
5
|
+
ESCAPE_TABLE = { '&'=>'&', '<'=>'<', '>'=>'>', '"'=>'"', "'"=>''', }
|
6
|
+
def h(value)
|
7
|
+
value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] }
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns an empty HTML tag of type +name+ which by default is XHTML
|
11
|
+
# compliant. Setting +open+ to true will create an open tag compatible
|
12
|
+
# with HTML 4.0 and below. Add HTML attributes by passing an attributes
|
13
|
+
# hash to +options+. For attributes with no value like (disabled and
|
14
|
+
# readonly), give it a value of true in the +options+ hash. You can use
|
15
|
+
# symbols or strings for the attribute names.
|
16
|
+
#
|
17
|
+
# tag("br")
|
18
|
+
# # => <br />
|
19
|
+
# tag("br", nil, true)
|
20
|
+
# # => <br>
|
21
|
+
# tag("input", { :type => 'text', :disabled => true })
|
22
|
+
# # => <input type="text" disabled="disabled" />
|
23
|
+
def tag(name, options = nil, open = false)
|
24
|
+
"<#{name}#{tag_options(options) if options}" + (open ? ">" : " />")
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the escaped +html+ without affecting existing escaped entities.
|
28
|
+
#
|
29
|
+
# escape_once("1 > 2 & 3")
|
30
|
+
# # => "1 < 2 & 3"
|
31
|
+
def escape_once(html)
|
32
|
+
fix_double_escape(h(html.to_s))
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def tag_options(options)
|
38
|
+
cleaned_options = convert_booleans(options.stringify_keys.reject {|key, value| value.nil?})
|
39
|
+
' ' + cleaned_options.map {|key, value| %(#{key}="#{escape_once(value)}")}.sort * ' ' unless cleaned_options.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def convert_booleans(options)
|
43
|
+
%w( disabled readonly multiple ).each { |a| boolean_attribute(options, a) }
|
44
|
+
options
|
45
|
+
end
|
46
|
+
|
47
|
+
def boolean_attribute(options, attribute)
|
48
|
+
options[attribute] ? options[attribute] = attribute : options.delete(attribute)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Fix double-escaped entities, such as &amp;, &#123;, etc.
|
52
|
+
def fix_double_escape(escaped)
|
53
|
+
escaped.gsub(/&([a-z]+|(#\d+));/i) { "&#{$1};" }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Waves
|
2
|
+
module Helpers
|
3
|
+
module UrlHelper
|
4
|
+
|
5
|
+
# Returns the URL for the set of +options+ provided. This takes the
|
6
|
+
# same options as url_for in action controller. For a list, see the
|
7
|
+
# documentation for ActionController::Base#url_for. Note that it'll
|
8
|
+
# set :only_path => true so you'll get the relative /controller/action
|
9
|
+
# instead of the fully qualified http://example.com/controller/action.
|
10
|
+
#
|
11
|
+
# When called from a view, url_for returns an HTML escaped url. If you
|
12
|
+
# need an unescaped url, pass :escape => false in the +options+.
|
13
|
+
def url_for(options = {}, *parameters_for_method_reference)
|
14
|
+
if options.kind_of? Hash
|
15
|
+
options = { :only_path => true }.update(options.symbolize_keys)
|
16
|
+
escape = options.key?(:escape) ? options.delete(:escape) : true
|
17
|
+
else
|
18
|
+
escape = true
|
19
|
+
end
|
20
|
+
|
21
|
+
url = options[:url] #@controller.send(:url_for, options, *parameters_for_method_reference)
|
22
|
+
escape ? html_escape(url) : url
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Creates a link tag of the given +name+ using a URL created by the set
|
27
|
+
# of +options+. See the valid options in the documentation for
|
28
|
+
# ActionController::Base#url_for. It's also possible to pass a string instead
|
29
|
+
# of an options hash to get a link tag that uses the value of the string as the
|
30
|
+
# href for the link. If nil is passed as a name, the link itself will become
|
31
|
+
# the name.
|
32
|
+
#
|
33
|
+
# The +html_options+ will accept a hash of html attributes for the link tag.
|
34
|
+
# It also accepts 3 modifiers that specialize the link behavior.
|
35
|
+
#
|
36
|
+
# * <tt>:confirm => 'question?'</tt>: This will add a JavaScript confirm
|
37
|
+
# prompt with the question specified. If the user accepts, the link is
|
38
|
+
# processed normally, otherwise no action is taken.
|
39
|
+
# * <tt>:popup => true || array of window options</tt>: This will force the
|
40
|
+
# link to open in a popup window. By passing true, a default browser window
|
41
|
+
# will be opened with the URL. You can also specify an array of options
|
42
|
+
# that are passed-thru to JavaScripts window.open method.
|
43
|
+
# * <tt>:method => symbol of HTTP verb</tt>: This modifier will dynamically
|
44
|
+
# create an HTML form and immediately submit the form for processing using
|
45
|
+
# the HTTP verb specified. Useful for having links perform a POST operation
|
46
|
+
# in dangerous actions like deleting a record (which search bots can follow
|
47
|
+
# while spidering your site). Supported verbs are :post, :delete and :put.
|
48
|
+
# Note that if the user has JavaScript disabled, the request will fall back
|
49
|
+
# to using GET. If you are relying on the POST behavior, your should check
|
50
|
+
# for it in your controllers action by using the request objects methods
|
51
|
+
# for post?, delete? or put?.
|
52
|
+
#
|
53
|
+
# You can mix and match the +html_options+ with the exception of
|
54
|
+
# :popup and :method which will raise an ActionView::ActionViewError
|
55
|
+
# exception.
|
56
|
+
#
|
57
|
+
# link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
|
58
|
+
# link_to "Help", { :action => "help" }, :popup => true
|
59
|
+
# link_to "View Image", { :action => "view" }, :popup => ['new_window_name', 'height=300,width=600']
|
60
|
+
# link_to "Delete Image", { :action => "delete", :id => @image.id }, :confirm => "Are you sure?", :method => :delete
|
61
|
+
def link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
|
62
|
+
if html_options
|
63
|
+
html_options = html_options.stringify_keys
|
64
|
+
# convert_options_to_javascript!(html_options)
|
65
|
+
tag_options = tag_options(html_options)
|
66
|
+
else
|
67
|
+
tag_options = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
url = options.is_a?(String) ? options : self.url_for(options, *parameters_for_method_reference)
|
71
|
+
"<a href=\"#{url}\"#{tag_options}>#{name || url}</a>"
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,23 +1,25 @@
|
|
1
1
|
module Waves
|
2
2
|
module Layers
|
3
|
+
|
4
|
+
# Configures Waves to use the templates in app/templates/errors for exception handling
|
3
5
|
module DefaultErrors
|
4
6
|
|
5
7
|
def self.included( app )
|
6
8
|
|
7
|
-
app.
|
8
|
-
|
9
|
-
|
9
|
+
app.auto_eval :Configurations do
|
10
|
+
auto_eval :Mapping do
|
11
|
+
extend Waves::Mapping
|
10
12
|
handle(Waves::Dispatchers::NotFoundError) do
|
11
13
|
html = Waves.application.views[:errors].process( request ) do
|
12
14
|
not_found_404( :error => Waves::Dispatchers::NotFoundError )
|
13
15
|
end
|
14
16
|
response.status = '404'
|
15
17
|
response.content_type = 'text/html'
|
16
|
-
response.
|
18
|
+
response.body = html
|
17
19
|
end
|
18
20
|
end
|
19
|
-
|
20
21
|
end
|
22
|
+
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
data/lib/layers/mvc.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Waves
|
2
|
+
module Layers
|
3
|
+
# The MVC layer establishes the Models, Views, Controllers, and Helpers namespaces inside
|
4
|
+
# a Waves application. In each namespace, undefined constants are handled by AutoCode, which
|
5
|
+
# loads the constant from the correct file in the appropriate directory if it exists, or creates
|
6
|
+
# from default otherwise.
|
7
|
+
module MVC
|
8
|
+
|
9
|
+
def self.included( app )
|
10
|
+
|
11
|
+
def app.models ; self::Models ; end
|
12
|
+
def app.views ; self::Views ; end
|
13
|
+
def app.controllers ; self::Controllers ; end
|
14
|
+
def app.helpers ; self::Helpers ; end
|
15
|
+
|
16
|
+
app.auto_create_module( :Models ) do
|
17
|
+
include AutoCode
|
18
|
+
auto_create_class :Default
|
19
|
+
auto_load :Default, :directories => [:models]
|
20
|
+
end
|
21
|
+
|
22
|
+
app.auto_eval( :Models ) do
|
23
|
+
auto_create_class true, app::Models::Default
|
24
|
+
auto_load true, :directories => [ :models ]
|
25
|
+
end
|
26
|
+
|
27
|
+
app.auto_create_module( :Views ) { include AutoCode }
|
28
|
+
|
29
|
+
app.auto_eval( :Views ) do
|
30
|
+
auto_create_class :Default, Waves::Views::Base
|
31
|
+
auto_load :Default, :directories => [:views]
|
32
|
+
auto_create_class true, app::Views::Default
|
33
|
+
auto_load true, :directories => [ :views ]
|
34
|
+
end
|
35
|
+
|
36
|
+
app.auto_create_module( :Controllers ) { include AutoCode }
|
37
|
+
|
38
|
+
app.auto_eval( :Controllers ) do
|
39
|
+
auto_create_class :Default, Waves::Controllers::Base
|
40
|
+
auto_load :Default, :directories => [:controllers]
|
41
|
+
auto_create_class true, app::Controllers::Default
|
42
|
+
auto_load true, :directories => [ :controllers ]
|
43
|
+
end
|
44
|
+
|
45
|
+
app.auto_create_module( :Helpers ) do
|
46
|
+
include AutoCode
|
47
|
+
auto_create_module { include Waves::Helpers::Default }
|
48
|
+
auto_load true, :directories => [ :helpers ]
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class Symbol
|
2
|
+
# Protect ActiveRecord from itself by undefining the to_proc method.
|
3
|
+
# Don't worry, AR will redefine it.
|
4
|
+
alias :extensions_to_proc :to_proc
|
5
|
+
remove_method :to_proc
|
6
|
+
end
|
7
|
+
require 'active_record'
|
8
|
+
require "#{File.dirname(__FILE__)}/active_record/tasks/schema" if defined?(Rake)
|
9
|
+
require "#{File.dirname(__FILE__)}/active_record/tasks/generate" if defined?(Rake)
|
10
|
+
|
11
|
+
|
12
|
+
module Waves
|
13
|
+
module Layers
|
14
|
+
module ORM
|
15
|
+
|
16
|
+
# Sets up the ActiveRecord connection and configures AutoCode on Models, so that constants in that
|
17
|
+
# namespace get loaded from file or created as subclasses of Models::Default
|
18
|
+
module ActiveRecord
|
19
|
+
|
20
|
+
# On inclusion, this module:
|
21
|
+
# - creates on the application module a database method that establishes and returns the ActiveRecord connection
|
22
|
+
# - arranges for autoloading/autocreation of missing constants in the Models namespace
|
23
|
+
# - defines ActiveRecord-specific helper methods on Waves::Controllers::Base
|
24
|
+
#
|
25
|
+
# The controller helper methdods are:
|
26
|
+
# - all
|
27
|
+
# - find(name)
|
28
|
+
# - create
|
29
|
+
# - delete(name)
|
30
|
+
# - update(name)
|
31
|
+
|
32
|
+
def self.included(app)
|
33
|
+
|
34
|
+
def app.database
|
35
|
+
unless @database
|
36
|
+
::ActiveRecord::Base.establish_connection(config.database)
|
37
|
+
@database = ::ActiveRecord::Base.connection
|
38
|
+
end
|
39
|
+
@database
|
40
|
+
end
|
41
|
+
|
42
|
+
app.auto_create_module( :Models ) do
|
43
|
+
include AutoCode
|
44
|
+
auto_create_class :Default, ::ActiveRecord::Base
|
45
|
+
auto_load :Default, :directories => [ :models ]
|
46
|
+
end
|
47
|
+
|
48
|
+
app.auto_eval :Models do
|
49
|
+
auto_create_class true, app::Models::Default
|
50
|
+
auto_load true, :directories => [ :models ]
|
51
|
+
|
52
|
+
auto_eval true do
|
53
|
+
app.database
|
54
|
+
set_table_name basename.snake_case.pluralize.intern
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Waves::Controllers::Base.instance_eval do
|
59
|
+
include Waves::Layers::ORM::ActiveRecord::ControllerMethods
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
# Mixed into Waves::Controllers::Base. Provides ORM-specific helper methods for model access.
|
65
|
+
module ControllerMethods
|
66
|
+
def all
|
67
|
+
model.find(:all)
|
68
|
+
end
|
69
|
+
|
70
|
+
def find( id )
|
71
|
+
model.find(id) or not_found
|
72
|
+
end
|
73
|
+
|
74
|
+
def create
|
75
|
+
model.create( attributes )
|
76
|
+
end
|
77
|
+
|
78
|
+
def delete( id )
|
79
|
+
find( id ).destroy
|
80
|
+
end
|
81
|
+
|
82
|
+
def update( id )
|
83
|
+
instance = find( id )
|
84
|
+
instance.update_attributes( attributes )
|
85
|
+
instance
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|