nyanko 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +25 -0
- data/MIT-LICENSE +22 -0
- data/README.md +105 -0
- data/Rakefile +1 -0
- data/lib/nyanko/active_if.rb +57 -0
- data/lib/nyanko/config.rb +13 -0
- data/lib/nyanko/controller.rb +23 -0
- data/lib/nyanko/function.rb +50 -0
- data/lib/nyanko/helper.rb +29 -0
- data/lib/nyanko/invoker/function_finder.rb +48 -0
- data/lib/nyanko/invoker/options.rb +69 -0
- data/lib/nyanko/invoker.rb +68 -0
- data/lib/nyanko/loader.rb +59 -0
- data/lib/nyanko/railtie.rb +13 -0
- data/lib/nyanko/unit/extender/active_record_class_methods.rb +56 -0
- data/lib/nyanko/unit/extender/extension.rb +51 -0
- data/lib/nyanko/unit/extender.rb +21 -0
- data/lib/nyanko/unit/scope_finder.rb +41 -0
- data/lib/nyanko/unit.rb +86 -0
- data/lib/nyanko/unit_proxy.rb +30 -0
- data/lib/nyanko/unit_proxy_provider.rb +21 -0
- data/lib/nyanko/version.rb +3 -0
- data/lib/nyanko.rb +16 -0
- data/nyanko.gemspec +29 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +14 -0
- data/spec/dummy/app/assets/stylesheets/main.scss +21 -0
- data/spec/dummy/app/assets/stylesheets/reset.scss +14 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/entries_controller.rb +33 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/entry.rb +3 -0
- data/spec/dummy/app/units/entry_deletion/entry_deletion.rb +37 -0
- data/spec/dummy/app/units/entry_deletion/views/_delete_link.html.slim +1 -0
- data/spec/dummy/app/views/entries/edit.html.slim +14 -0
- data/spec/dummy/app/views/entries/index.html.slim +5 -0
- data/spec/dummy/app/views/entries/show.html.slim +8 -0
- data/spec/dummy/app/views/layouts/application.html.slim +16 -0
- data/spec/dummy/config/application.rb +68 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20130127170331_create_entries.rb +11 -0
- data/spec/dummy/db/schema.rb +24 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/fixtures/units/example_unit/example_unit.rb +53 -0
- data/spec/fixtures/units/inactive_unit/inactive_unit.rb +11 -0
- data/spec/nyanko/controller_spec.rb +39 -0
- data/spec/nyanko/function_spec.rb +40 -0
- data/spec/nyanko/helper_spec.rb +26 -0
- data/spec/nyanko/invoker_spec.rb +116 -0
- data/spec/nyanko/loader_spec.rb +43 -0
- data/spec/nyanko/unit/extender_spec.rb +40 -0
- data/spec/nyanko/unit/scope_finder_spec.rb +37 -0
- data/spec/nyanko/unit_proxy_provider_spec.rb +40 -0
- data/spec/nyanko/unit_proxy_spec.rb +23 -0
- data/spec/nyanko/unit_spec.rb +169 -0
- data/spec/spec_helper.rb +21 -0
- metadata +320 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: 3bf6a9e3b51bc80536b6dd54ca34a36cce8bde19
|
4
|
+
data.tar.gz: ee455931da637b0687a514b177bdbcb42a43c1b1
|
5
|
+
!binary "U0hBNTEy":
|
6
|
+
metadata.gz: 49253ba6ec4aa0195957714b64ab93802ed1727c3af38a90b2c7bf003f861517209261f2e1c9a0a8b3d9e5b39191fe09d526bc4d03ce9cc0696db4180ac9a3dd
|
7
|
+
data.tar.gz: 29bb6270a940e5a74208536928f58c547c9b4fa042f69135e92a672b2dbf6b4458de9f388d7feaa58dbef81340c686131dddfe9096a8735ae63d0f2fa2598041
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
log/*.log
|
2
|
+
spec/dummy/db/*.sqlite3
|
3
|
+
spec/dummy/log/*.log
|
4
|
+
spec/dummy/tmp/
|
5
|
+
spec/dummy/.sass-cache
|
6
|
+
*.gem
|
7
|
+
*.rbc
|
8
|
+
.bundle
|
9
|
+
.config
|
10
|
+
.yardoc
|
11
|
+
Gemfile.lock
|
12
|
+
InstalledFiles
|
13
|
+
_yardoc
|
14
|
+
coverage
|
15
|
+
doc/
|
16
|
+
lib/bundler/man
|
17
|
+
pkg
|
18
|
+
rdoc
|
19
|
+
spec/reports
|
20
|
+
test/tmp
|
21
|
+
test/version_tmp
|
22
|
+
tmp
|
data/Gemfile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
group :development, :test, :production do
|
6
|
+
gem "jquery-rails"
|
7
|
+
gem "quiet_assets"
|
8
|
+
gem "rails", ">= 3.0.10"
|
9
|
+
gem "slim"
|
10
|
+
gem "sqlite3"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem "rspec-rails", "2.12.2"
|
15
|
+
end
|
16
|
+
|
17
|
+
group :development, :test do
|
18
|
+
gem "pry-rails"
|
19
|
+
end
|
20
|
+
|
21
|
+
group :assets do
|
22
|
+
gem "sass-rails", ">= 3.0.10"
|
23
|
+
gem "coffee-rails", ">= 3.0.10"
|
24
|
+
gem "uglifier"
|
25
|
+
end
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ryo Nakamura
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Nyanko
|
2
|
+
Nyanko is a Rails extension tool.
|
3
|
+
This is deeply inspired from [Chanko](https://github.com/cookpad/chanko) and has same API as Chanko.
|
4
|
+
|
5
|
+
![](http://octodex.github.com/images/nyantocat.gif)
|
6
|
+
|
7
|
+
|
8
|
+
## Requirements
|
9
|
+
* Ruby >= 1.8.7
|
10
|
+
* Rails >= 3.0.10
|
11
|
+
|
12
|
+
|
13
|
+
## Install
|
14
|
+
```
|
15
|
+
$ gem install nyanko
|
16
|
+
```
|
17
|
+
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Gemfile
|
22
|
+
```ruby
|
23
|
+
# Gemfile
|
24
|
+
gem "nyanko"
|
25
|
+
```
|
26
|
+
|
27
|
+
### Invoke
|
28
|
+
```ruby
|
29
|
+
class EntriesController < ApplicationController
|
30
|
+
unit_action :entry_deletion, :destroy
|
31
|
+
|
32
|
+
def index
|
33
|
+
invoke(:entry_deletion, :index) do
|
34
|
+
@entries = Entry.all
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
### Unit
|
41
|
+
```ruby
|
42
|
+
# app/units/entry_deletion/entry_deletion.rb
|
43
|
+
module EntryDeletion
|
44
|
+
include Nyanko::Unit
|
45
|
+
|
46
|
+
active_if { Rails.env.development? }
|
47
|
+
|
48
|
+
scope(:view) do
|
49
|
+
function(:delete_link) do
|
50
|
+
render "/delete_link", :entry => entry if entry.persisted?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
scope(:controller) do
|
55
|
+
function(:destroy) do
|
56
|
+
entry = Entry.find(params[:id])
|
57
|
+
entry.unit.soft_delete
|
58
|
+
redirect_to entries_path
|
59
|
+
end
|
60
|
+
|
61
|
+
function(:index) do
|
62
|
+
@entries = Entry.unit.active
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
models do
|
67
|
+
expand(:Entry) do
|
68
|
+
scope :active, lambda { where(:deleted_at => nil) }
|
69
|
+
|
70
|
+
def soft_delete
|
71
|
+
update_attributes(:deleted_at => Time.now)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
helpers do
|
77
|
+
def link_to_deletion(entry)
|
78
|
+
link_to "Delete", entry, :method => :delete
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
```
|
85
|
+
-# app/units/entry_deletion/views/_delete_link.html.slim
|
86
|
+
= unit.link_to_deletion(entry)
|
87
|
+
```
|
88
|
+
|
89
|
+
|
90
|
+
## Example App
|
91
|
+
There is an example rails application for Nyanko in spec/dummy directory.
|
92
|
+
```
|
93
|
+
$ git clone git@github.com:r7kamura/nyanko.git
|
94
|
+
$ cd nyanko/spec/dummy
|
95
|
+
$ rails s
|
96
|
+
```
|
97
|
+
|
98
|
+
|
99
|
+
## Todo
|
100
|
+
* auto-reloading
|
101
|
+
* logger
|
102
|
+
* configuration
|
103
|
+
* backwoard compatibility (alias ext to unit)
|
104
|
+
* document
|
105
|
+
* test (for now, test coverage is 100%)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Nyanko
|
2
|
+
class ActiveIf
|
3
|
+
class << self
|
4
|
+
def define(label, &block)
|
5
|
+
definitions[label] = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def find(label)
|
9
|
+
definitions[label]
|
10
|
+
end
|
11
|
+
|
12
|
+
def definitions
|
13
|
+
@definitions ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear
|
17
|
+
definitions.clear
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(*conditions, &block)
|
22
|
+
@options = conditions.extract_options!
|
23
|
+
@conditions = conditions
|
24
|
+
@block = block
|
25
|
+
end
|
26
|
+
|
27
|
+
def active?(context, options = {})
|
28
|
+
blocks.all? {|block| block.call(context, options) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def blocks
|
32
|
+
@blocks ||= begin
|
33
|
+
@conditions.map do |condition|
|
34
|
+
condition.is_a?(Any) ? condition.to_block : self.class.find(condition)
|
35
|
+
end << @block
|
36
|
+
end.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
class Any
|
40
|
+
def initialize(*labels)
|
41
|
+
@labels = labels
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_block
|
45
|
+
proc do |context, options|
|
46
|
+
definitions.any? do |definition|
|
47
|
+
definition.call(context, options)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def definitions
|
53
|
+
@labels.map {|label| ActiveIf.find(label) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Nyanko
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include Invoker
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
private
|
11
|
+
|
12
|
+
def unit_action(unit_name, *function_names, &block)
|
13
|
+
options = function_names.extract_options!
|
14
|
+
block ||= Proc.new { head 400 }
|
15
|
+
Array.wrap(function_names).each do |function_name|
|
16
|
+
define_method(function_name) do
|
17
|
+
invoke(unit_name, function_name, options, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Nyanko
|
2
|
+
class Function
|
3
|
+
attr_reader :block, :unit, :label
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def units
|
7
|
+
@units ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def current_unit
|
11
|
+
units.last
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(unit, label, &block)
|
16
|
+
@unit = unit
|
17
|
+
@label = label
|
18
|
+
@block = block
|
19
|
+
end
|
20
|
+
|
21
|
+
def invoke(context, options = {})
|
22
|
+
with_unit_stack(context) do
|
23
|
+
with_unit_view_path(context) do
|
24
|
+
context.instance_eval(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def with_unit_stack(context)
|
32
|
+
context.units << @unit
|
33
|
+
self.class.units << @unit
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
self.class.units.pop
|
37
|
+
context.units.pop
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_unit_view_path(context)
|
41
|
+
if context.view?
|
42
|
+
origin = context.view_paths
|
43
|
+
context.view_paths.unshift unit.view_path
|
44
|
+
end
|
45
|
+
yield
|
46
|
+
ensure
|
47
|
+
context.view_paths = origin if context.view?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Nyanko
|
2
|
+
module Helper
|
3
|
+
class << self
|
4
|
+
def define(class_name, &block)
|
5
|
+
prefix = UnitProxy.generate_prefix(class_name)
|
6
|
+
define_methods_with_prefix(prefix, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def define_methods_with_prefix(prefix, &block)
|
10
|
+
define_methods(&block).each do |name|
|
11
|
+
change_method_name(name, "#{prefix}#{name}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_methods(&block)
|
16
|
+
before = instance_methods(false)
|
17
|
+
self.class_eval(&block)
|
18
|
+
instance_methods(false) - before
|
19
|
+
end
|
20
|
+
|
21
|
+
def change_method_name(from, to)
|
22
|
+
class_eval do
|
23
|
+
alias_method to, from
|
24
|
+
remove_method from
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Nyanko
|
2
|
+
module Invoker
|
3
|
+
class FunctionFinder
|
4
|
+
UnitNotFound = Class.new(StandardError)
|
5
|
+
FunctionNotFound = Class.new(StandardError)
|
6
|
+
|
7
|
+
def self.find(*args)
|
8
|
+
new(*args).find or raise FunctionNotFound
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(context, options)
|
12
|
+
@context = context
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def find
|
17
|
+
@options[:functions].find do |unit_name, label|
|
18
|
+
unit = find_unit(unit_name)
|
19
|
+
identifier = @options[:as] || @context.class
|
20
|
+
next unless unit.active?(@context, @options[:active_if_options])
|
21
|
+
function = unit.find_function(identifier, label)
|
22
|
+
break function if function
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_with_dependencies
|
27
|
+
find_without_dependencies unless has_inactive_dependent_unit?
|
28
|
+
end
|
29
|
+
alias_method_chain :find, :dependencies
|
30
|
+
|
31
|
+
def find_unit(name)
|
32
|
+
Loader.load(name) or raise UnitNotFound
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_inactive_dependent_unit?
|
36
|
+
dependent_units.any? {|unit| !unit.active?(@context, @options[:active_if_options]) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def dependent_units
|
40
|
+
dependent_unit_names.map {|name| find_unit(name) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def dependent_unit_names
|
44
|
+
Array.wrap(@options[:dependencies])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Nyanko
|
2
|
+
module Invoker
|
3
|
+
class Options
|
4
|
+
CANDIDATES = {
|
5
|
+
:active_if_options => true,
|
6
|
+
:as => true,
|
7
|
+
:capture => true,
|
8
|
+
:if => true,
|
9
|
+
:locals => true,
|
10
|
+
:type => true,
|
11
|
+
}
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
@raw_options = args.extract_options!
|
15
|
+
@args = args
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
send(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def functions
|
23
|
+
@args.first.is_a?(Array) ? @args : [[@args[0], @args[1]]]
|
24
|
+
end
|
25
|
+
|
26
|
+
def locals
|
27
|
+
(options[:locals] || {}).symbolize_keys
|
28
|
+
end
|
29
|
+
|
30
|
+
def active_if_options
|
31
|
+
options[:active_if_options] || {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def as
|
35
|
+
options[:as]
|
36
|
+
end
|
37
|
+
|
38
|
+
def dependencies
|
39
|
+
options[:if]
|
40
|
+
end
|
41
|
+
|
42
|
+
def capture
|
43
|
+
options.has_key?(:capture) ? capture[:capture] : true
|
44
|
+
end
|
45
|
+
|
46
|
+
def type
|
47
|
+
options[:type]
|
48
|
+
end
|
49
|
+
|
50
|
+
def invoke_options
|
51
|
+
{ :capture => capture, :type => type }
|
52
|
+
end
|
53
|
+
|
54
|
+
def options
|
55
|
+
@options ||= begin
|
56
|
+
if short_hand_options?
|
57
|
+
{ :locals => @raw_options }
|
58
|
+
else
|
59
|
+
@raw_options
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def short_hand_options?
|
65
|
+
@raw_options.any? && @raw_options.keys.all? {|key| !CANDIDATES[key] }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "nyanko/invoker/options"
|
2
|
+
require "nyanko/invoker/function_finder"
|
3
|
+
|
4
|
+
module Nyanko
|
5
|
+
module Invoker
|
6
|
+
def invoke(*args, &block)
|
7
|
+
options = Options.new(*args)
|
8
|
+
unit_locals_stack << options.locals
|
9
|
+
function = FunctionFinder.find(self, options)
|
10
|
+
result = function.invoke(self, options.invoke_options)
|
11
|
+
result = surround_with_html_tag(result, function, options) if view?
|
12
|
+
result
|
13
|
+
rescue Exception
|
14
|
+
p $!
|
15
|
+
case
|
16
|
+
when !block
|
17
|
+
nil
|
18
|
+
when view?
|
19
|
+
capture(&block)
|
20
|
+
else
|
21
|
+
instance_exec(&block)
|
22
|
+
end
|
23
|
+
ensure
|
24
|
+
unit_locals_stack.pop
|
25
|
+
end
|
26
|
+
|
27
|
+
def units
|
28
|
+
@units ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
def view?
|
32
|
+
is_a?(ActionView::Base)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Search shared method or locals variable
|
38
|
+
def method_missing(method_name, *args, &block)
|
39
|
+
if (methods = units.last.try(:shared_methods)) && block = methods[method_name]
|
40
|
+
self.instance_exec(*args, &block)
|
41
|
+
elsif args.empty? && value = (unit_locals_stack.last || {})[method_name]
|
42
|
+
value
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def unit_locals_stack
|
49
|
+
@unit_locals_stack ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
def surround_with_html_tag(str, function, options)
|
53
|
+
classes = %W[
|
54
|
+
unit
|
55
|
+
unit__#{function.unit.name.underscore}
|
56
|
+
unit__#{function.unit.name.underscore}__#{function.label}
|
57
|
+
]
|
58
|
+
case options.type
|
59
|
+
when :plain
|
60
|
+
str
|
61
|
+
when :inline
|
62
|
+
content_tag(:span, str, :class => classes)
|
63
|
+
else
|
64
|
+
content_tag(:div, str, :class => classes)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module Nyanko
|
4
|
+
class Loader
|
5
|
+
class << self
|
6
|
+
def load(unit_name)
|
7
|
+
new(unit_name).load
|
8
|
+
end
|
9
|
+
|
10
|
+
def cache
|
11
|
+
@cache ||= {}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(name)
|
16
|
+
@name = name
|
17
|
+
end
|
18
|
+
|
19
|
+
def load
|
20
|
+
loaded? ? load_from_cache : load_from_file
|
21
|
+
end
|
22
|
+
|
23
|
+
def loaded?
|
24
|
+
cache[@name] != nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_from_cache
|
28
|
+
cache[@name]
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_from_file
|
32
|
+
require_unit_files
|
33
|
+
cache[@name] = constantize
|
34
|
+
rescue Exception
|
35
|
+
cache[@name] = false
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def require_unit_files
|
40
|
+
paths.each {|path| require Rails.root.join(path) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def paths
|
44
|
+
Pathname.glob("#{directory_path}/#@name/#@name.rb").sort
|
45
|
+
end
|
46
|
+
|
47
|
+
def directory_path
|
48
|
+
Config.units_directory_path
|
49
|
+
end
|
50
|
+
|
51
|
+
def constantize
|
52
|
+
@name.to_s.camelize.constantize
|
53
|
+
end
|
54
|
+
|
55
|
+
def cache
|
56
|
+
self.class.cache
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "rails"
|
2
|
+
|
3
|
+
module Nyanko
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
initializer "nyanko" do |app|
|
6
|
+
::ActionView::Base.send(:include, Invoker, Helper, UnitProxyProvider)
|
7
|
+
::ActionController::Base.send(:include, Controller)
|
8
|
+
::ActiveRecord::Base.send(:include, UnitProxyProvider)
|
9
|
+
::ActiveRecord::Relation.send(:include, UnitProxyProvider)
|
10
|
+
::ActiveRecord::Associations::CollectionAssociation.send(:include, UnitProxyProvider)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Nyanko
|
2
|
+
module Unit
|
3
|
+
class Extender
|
4
|
+
module ActiveRecordClassMethods
|
5
|
+
delegate(
|
6
|
+
:apply_modules,
|
7
|
+
:arel,
|
8
|
+
:array_of_strings?,
|
9
|
+
:build_arel,
|
10
|
+
:build_joins,
|
11
|
+
:build_select,
|
12
|
+
:build_where,
|
13
|
+
:create_with,
|
14
|
+
:custom_join_sql,
|
15
|
+
:eager_load,
|
16
|
+
:extending,
|
17
|
+
:from,
|
18
|
+
:group,
|
19
|
+
:having,
|
20
|
+
:includes,
|
21
|
+
:joins,
|
22
|
+
:limit,
|
23
|
+
:lock,
|
24
|
+
:offset,
|
25
|
+
:order,
|
26
|
+
:preload,
|
27
|
+
:readonly,
|
28
|
+
:reorder,
|
29
|
+
:reverse_order,
|
30
|
+
:reverse_sql_order,
|
31
|
+
:scope,
|
32
|
+
:select,
|
33
|
+
:where,
|
34
|
+
:to => :@mod
|
35
|
+
)
|
36
|
+
|
37
|
+
%w[belongs_to has_many has_one].each do |method_name|
|
38
|
+
class_eval <<-EOS
|
39
|
+
def #{method_name}(*args, &block)
|
40
|
+
name = @prefix + args.shift.to_s
|
41
|
+
options = args.extract_options!
|
42
|
+
options = options.reverse_merge(:class_name => @mod.to_s)
|
43
|
+
args << options
|
44
|
+
@mod.#{method_name}(name.to_sym, *args, &block)
|
45
|
+
end
|
46
|
+
EOS
|
47
|
+
end
|
48
|
+
|
49
|
+
def scope(*args, &block)
|
50
|
+
name = @prefix + args.shift.to_s
|
51
|
+
@mod.scope(name, *args)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|