nyanko 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+

|
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
|