nested_resource_url 0.1.0
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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/lib/nested_resource_url.rb +13 -0
- data/lib/nested_resource_url/collector.rb +76 -0
- data/lib/nested_resource_url/helpers.rb +52 -0
- data/lib/nested_resource_url/method_definer.rb +67 -0
- data/lib/nested_resource_url/nested_resource.rb +51 -0
- data/lib/nested_resource_url/version.rb +3 -0
- data/nested_resource_url.gemspec +20 -0
- data/spec/helper_spec.rb +26 -0
- data/spec/helpers/receiver.rb +14 -0
- data/spec/method_definer_call_merged_options_spec.rb +22 -0
- data/spec/method_definer_call_spec.rb +24 -0
- data/spec/method_definer_method_spec.rb +35 -0
- data/spec/nested_resource_spec.rb +60 -0
- data/spec/spec_helper.rb +34 -0
- metadata +89 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 menostos
|
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,51 @@
|
|
1
|
+
# NestedResourceUrl
|
2
|
+
|
3
|
+
this gem will add some functionality to the rails actioncontroller.
|
4
|
+
it'll provide the +nested_resource+ method which you can use to
|
5
|
+
specify the nesting. See Usage
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'nested_resource_url'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install nested_resource_url
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### routes.rb
|
24
|
+
|
25
|
+
resource :projects do
|
26
|
+
resource :tasks
|
27
|
+
end
|
28
|
+
|
29
|
+
### tasks_controller.rb
|
30
|
+
|
31
|
+
class TasksController < ...
|
32
|
+
nested_resource :task
|
33
|
+
end
|
34
|
+
|
35
|
+
this will make the following methods available to your controller and views
|
36
|
+
(example when a project is defined)
|
37
|
+
|
38
|
+
* nested_resource(@task) # => [<Project>, <Task>]
|
39
|
+
* nested_task_path(@task) # => /project/:project_id/tasks
|
40
|
+
* new_nested_task_path # => /project/:project_id/tasks/new
|
41
|
+
* edit_nested_task_path(@task) # => /project/:project_id/tasks/1/edit
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
1. Fork it
|
48
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
49
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
50
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
51
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
require 'nested_resource_url/version'
|
3
|
+
require 'active_support/concern'
|
4
|
+
require 'active_support/core_ext/string/inflections'
|
5
|
+
require 'active_support/core_ext/hash/slice'
|
6
|
+
require 'action_controller'
|
7
|
+
require 'nested_resource_url/collector'
|
8
|
+
require 'nested_resource_url/method_definer'
|
9
|
+
require 'nested_resource_url/nested_resource'
|
10
|
+
require 'nested_resource_url/helpers'
|
11
|
+
|
12
|
+
module NestedResourceUrl
|
13
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module NestedResourceUrl
|
2
|
+
|
3
|
+
# The class collects objects in a controller
|
4
|
+
# it is initialized with a controller and an array of object_names
|
5
|
+
class Collector < Struct.new(:controller, :object_names)
|
6
|
+
|
7
|
+
# Collects the resources specified when creating the
|
8
|
+
# collector. it'll also filter the array of resources
|
9
|
+
# according to the options
|
10
|
+
#
|
11
|
+
# === Options:
|
12
|
+
# * +:only+:: specify an array of symbols, classes or objects which are allowed to be returned
|
13
|
+
# * +:except+:: specify an array of symbols, classes or objects which are not allowed to be returned
|
14
|
+
# * +:max_level+:: specifies the max amount of objects returned
|
15
|
+
# * +:exclusive+:: if set to true it'll return no resources, same as max_level = 0
|
16
|
+
def resources(options = {})
|
17
|
+
resources = self.collect_resources(options)
|
18
|
+
|
19
|
+
return self.apply_only_and_except(resources, options).compact
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
# collects the resources without applying the only and except options
|
24
|
+
#
|
25
|
+
# === Options:
|
26
|
+
# * +:max_level+:: specifies the max amount of objects returned
|
27
|
+
# * +:exclusive+:: if set to true it'll return no resources, same as max_level = 0
|
28
|
+
def collect_resources(options)
|
29
|
+
max_level = self.max_nesting_level(options)
|
30
|
+
resources = NestedResourceUrl::NestedResource.new
|
31
|
+
|
32
|
+
self.object_names.each do |object_name|
|
33
|
+
break if resources.length >= max_level
|
34
|
+
resources << self.resource_from_object_name(object_name)
|
35
|
+
end
|
36
|
+
return resources
|
37
|
+
end
|
38
|
+
|
39
|
+
# evaluates the options only and except and filters the given resources
|
40
|
+
#
|
41
|
+
# === Options:
|
42
|
+
# * +:max_level+:: specifies the max amount of objects returned
|
43
|
+
# * +:exclusive+:: if set to true it'll return no resources, same as max_level = 0
|
44
|
+
def apply_only_and_except(resources, options)
|
45
|
+
resources = resources.only(options[:only]) if options.include?(:only)
|
46
|
+
resources = resources.except(options[:except]) if options.include?(:except)
|
47
|
+
return resources
|
48
|
+
end
|
49
|
+
|
50
|
+
# the method will lookup the object_name on the given controller.
|
51
|
+
# it'll search for the method with it's name or an instace variable
|
52
|
+
#
|
53
|
+
# === Params:
|
54
|
+
# * +object_name+: a symbol specifing an object_name
|
55
|
+
def resource_from_object_name(object_name)
|
56
|
+
if self.controller.respond_to?(object_name)
|
57
|
+
self.controller.send(object_name)
|
58
|
+
else
|
59
|
+
self.controller.instance_variable_get(:"@#{object_name}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# returns the max level of nesting allowed through options
|
64
|
+
|
65
|
+
# === Options:
|
66
|
+
# * +:max_level+:: specifies the max amount of objects returned
|
67
|
+
# * +:exclusive+:: if set to true it'll return no resources, same as max_level = 0
|
68
|
+
def max_nesting_level(options)
|
69
|
+
max_nesting_level = options.delete(:max_level) || 99
|
70
|
+
max_nesting_level = 0 if options.delete(:exclusive) === true
|
71
|
+
max_nesting_level
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module NestedResourceUrl
|
2
|
+
|
3
|
+
module Helpers
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
protected
|
8
|
+
# returns the options valid for collecting nested_resources
|
9
|
+
#
|
10
|
+
# Note: options will be modified
|
11
|
+
def extract_nested_collect_options!(options = {})
|
12
|
+
options.extract!(:max_level, :exclusive, :only, :except).select{|key, value| value }
|
13
|
+
end
|
14
|
+
|
15
|
+
# collects the resources for the given objects_names
|
16
|
+
#
|
17
|
+
# === Params:
|
18
|
+
# * +object_names+:: an array of symbols
|
19
|
+
# * +options+:: an options hash
|
20
|
+
#
|
21
|
+
# === Options:
|
22
|
+
# * +:only+:: specify an array of symbols, classes or objects which are allowed to be returned
|
23
|
+
# * +:except+:: specify an array of symbols, classes or objects which are not allowed to be returned
|
24
|
+
# * +:max_level+:: specifies the max amount of objects returned
|
25
|
+
# * +:exclusive+:: if set to true it'll return no resources, same as max_level = 0
|
26
|
+
def collect_nested_resource_objects(object_names, options = {})
|
27
|
+
return NestedResourceUrl::Collector.new(self, object_names).resources(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
protected
|
33
|
+
# setup the nested_resource methods for the current controller.
|
34
|
+
# creates the following methods where you need to replace the word task:
|
35
|
+
#
|
36
|
+
# * nested_task:: used for form_for
|
37
|
+
# * nested_task_path:: normal links
|
38
|
+
# * nested_task_url:: normal links
|
39
|
+
#
|
40
|
+
# === Options:
|
41
|
+
# * +:max_level+:: specifies the max amount of objects returned
|
42
|
+
def nested_resource(object, options = {})
|
43
|
+
nested_object_names = options.delete(:through)
|
44
|
+
MethodDefiner.new(self).define_methods!(object, nested_object_names, options)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
ActionController::Base.send :include, NestedResourceUrl::Helpers
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module NestedResourceUrl
|
2
|
+
|
3
|
+
class MethodDefiner < Struct.new(:receiver)
|
4
|
+
|
5
|
+
# define the methods on the given receiver
|
6
|
+
#
|
7
|
+
# === Params:
|
8
|
+
# * scope_name: the symbol which object to nest
|
9
|
+
# * object_names: an array of symbols to nest
|
10
|
+
# * default_options: an options hash
|
11
|
+
def define_methods!(scope_name, object_names, default_options)
|
12
|
+
define_nested_helper_method(scope_name, object_names, default_options)
|
13
|
+
define_nested_url_methods(scope_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def define_nested_url_methods(object_name)
|
17
|
+
pluralized_object_name = object_name.to_s.pluralize
|
18
|
+
[:path, :url].each do |type|
|
19
|
+
define_nested_url_method_show_and_edit(object_name, type)
|
20
|
+
define_nested_url_method_new(object_name, type)
|
21
|
+
define_nested_url_method_index(object_name, pluralized_object_name, type)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def define_nested_url_method_show_and_edit(scope_name, type)
|
26
|
+
[nil, :edit_].each do |action|
|
27
|
+
method_name = :"#{action}nested_#{scope_name}_#{type}"
|
28
|
+
self.receiver.class_eval <<-EOF
|
29
|
+
def #{method_name}(object, options = {})
|
30
|
+
self.#{action}polymorphic_#{type}(self.nested_#{scope_name}(object, extract_nested_collect_options!(options)), options)
|
31
|
+
end
|
32
|
+
EOF
|
33
|
+
self.receiver.send(:helper_method, method_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_nested_url_method_new(scope_name, type)
|
38
|
+
new_method_name = :"new_nested_#{scope_name}_#{type}"
|
39
|
+
self.receiver.class_eval <<-EOF
|
40
|
+
def #{new_method_name}(options = {})
|
41
|
+
self.new_polymorphic_#{type}(self.nested_#{scope_name}(:#{scope_name}, extract_nested_collect_options!(options)), options)
|
42
|
+
end
|
43
|
+
EOF
|
44
|
+
self.receiver.send(:helper_method, new_method_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def define_nested_url_method_index(scope_name, plural_scope_name, type)
|
48
|
+
index_method_name = :"nested_#{plural_scope_name}_#{type}"
|
49
|
+
self.receiver.class_eval <<-EOF
|
50
|
+
def #{index_method_name}(options = {})
|
51
|
+
self.polymorphic_#{type}(self.nested_#{scope_name}(:#{plural_scope_name}, extract_nested_collect_options!(options)), options)
|
52
|
+
end
|
53
|
+
EOF
|
54
|
+
self.receiver.send(:helper_method, index_method_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def define_nested_helper_method(scope_name, object_names, default_options = {})
|
58
|
+
method_name = :"nested_#{scope_name}"
|
59
|
+
receiver.send(:define_method, method_name) do |object, options = {}|
|
60
|
+
self.collect_nested_resource_objects(object_names, default_options.merge(options)) + [object]
|
61
|
+
end
|
62
|
+
self.receiver.send(:helper_method, method_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NestedResourceUrl
|
2
|
+
|
3
|
+
# Nested resource extends the array overiding the "-" and the "&" method to
|
4
|
+
# filter elements with symbol, class or object itself
|
5
|
+
class NestedResource < Array
|
6
|
+
|
7
|
+
# returns a new array without any object within +other+ that matches
|
8
|
+
# one of this
|
9
|
+
#
|
10
|
+
# === Params:
|
11
|
+
# * +other+:: an object or array of objects containing symbols, class or object
|
12
|
+
def -(*other)
|
13
|
+
objects_to_delete = other.flatten
|
14
|
+
self.select do |resource|
|
15
|
+
!self.contains_type_of(resource, objects_to_delete)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# returns a new array only containing the objects given with other
|
20
|
+
#
|
21
|
+
# === Params:
|
22
|
+
# * +other+:: an object or array of objects containing symbols, class or object
|
23
|
+
def &(*other)
|
24
|
+
objects_to_keep = other.flatten
|
25
|
+
self.select do |resource|
|
26
|
+
self.contains_type_of(resource, objects_to_keep)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
alias :except :-
|
30
|
+
alias :only :&
|
31
|
+
|
32
|
+
protected
|
33
|
+
# checks if the resource is within the object_to_checks.
|
34
|
+
# returns true if:
|
35
|
+
#
|
36
|
+
# * the objects_to_check contains the resource itself
|
37
|
+
# * the objects_to_check contains a symbol matching the classname
|
38
|
+
# * the objects_to_check contains the resources class
|
39
|
+
def contains_type_of(resource, objects_to_check)
|
40
|
+
objects_to_check.include?(resource) ||
|
41
|
+
objects_to_check.include?(self.resource_name(resource)) ||
|
42
|
+
objects_to_check.include?(resource.class)
|
43
|
+
end
|
44
|
+
|
45
|
+
def resource_name(resource)
|
46
|
+
resource.class.name.underscore.to_sym
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nested_resource_url/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "nested_resource_url"
|
8
|
+
gem.version = NestedResourceUrl::VERSION
|
9
|
+
gem.authors = ["menostos"]
|
10
|
+
gem.email = ["menostos@gmail.com"]
|
11
|
+
gem.description = %q{The gem will add some helpers to controllers and view to automatically create nested urls}
|
12
|
+
gem.summary = %q{nested url helper for controller and views}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
gem.add_dependency("activesupport", ["~> 3.0"])
|
20
|
+
end
|
data/spec/helper_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe NestedResourceUrl::Helpers do
|
5
|
+
|
6
|
+
class Helper
|
7
|
+
include NestedResourceUrl::Helpers
|
8
|
+
end
|
9
|
+
|
10
|
+
subject{
|
11
|
+
Helper.new
|
12
|
+
}
|
13
|
+
|
14
|
+
it 'should extract valid NestedResourceUrl with optional options' do
|
15
|
+
options = {max_level: 5, test: "number1"}
|
16
|
+
subject.send(:extract_nested_collect_options!, options).should eq({max_level: 5})
|
17
|
+
options.should eq(test: "number1")
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should extract valid NestedResourceUrl with all options' do
|
21
|
+
options = {max_level: 5, test: "number1", exclusive: true, only: :project, except: :user, another: :param}
|
22
|
+
subject.send(:extract_nested_collect_options!, options).should eq({max_level: 5, exclusive: true, only: :project, except: :user})
|
23
|
+
options.should eq(test: "number1", another: :param)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe NestedResourceUrl::MethodDefiner do
|
5
|
+
|
6
|
+
setup_receiver!(options: {max_level: 5})
|
7
|
+
|
8
|
+
it 'should collect_nested_resource_objects with merged options' do
|
9
|
+
setup_subject!(options: {max_level: 5, exclusive: true}).should_receive(:task_path)
|
10
|
+
subject.nested_task_path(:task, {exclusive: true})
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should override default_options with options' do
|
14
|
+
setup_subject!(options: {max_level: 7}).should_receive(:task_path)
|
15
|
+
subject.nested_task_path(:task, {max_level: 7})
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should' do
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe NestedResourceUrl::MethodDefiner do
|
5
|
+
|
6
|
+
setup_receiver!
|
7
|
+
|
8
|
+
it 'should return the task alone when no objects available' do
|
9
|
+
setup_subject!
|
10
|
+
subject.nested_task(:task).should eq([:task])
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should return the project with the task' do
|
14
|
+
project = Project.new
|
15
|
+
setup_subject! nested_resources: [project]
|
16
|
+
subject.nested_task(:task).should eq([project, :task])
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should collect_nested_resource_objects with options' do
|
20
|
+
setup_subject!(options: {max_level: 5}).should_receive(:task_path)
|
21
|
+
subject.nested_task_path(:task, {max_level: 5})
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe NestedResourceUrl::MethodDefiner do
|
5
|
+
|
6
|
+
setup_receiver!
|
7
|
+
|
8
|
+
[:path, :url].each do |type|
|
9
|
+
{
|
10
|
+
1 => [
|
11
|
+
:"new_nested_task_#{type}",
|
12
|
+
:"nested_tasks_#{type}"
|
13
|
+
],
|
14
|
+
2 => [
|
15
|
+
:"nested_task_#{type}",
|
16
|
+
:"edit_nested_task_#{type}",
|
17
|
+
]
|
18
|
+
}.each do |parameter_count, method_names|
|
19
|
+
method_names.each do |method_name|
|
20
|
+
|
21
|
+
it "it should define #{method_name} with #{parameter_count}" do
|
22
|
+
subject.should respond_to(method_name)
|
23
|
+
subject.method(method_name).arity.should eq(-parameter_count) # options is optional
|
24
|
+
subject.method(method_name).parameters.length.should eq(parameter_count)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should define the nested_task method with' do
|
31
|
+
subject.should respond_to(:nested_task)
|
32
|
+
subject.method(:nested_task).arity.should eq(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe NestedResourceUrl::NestedResource do
|
5
|
+
|
6
|
+
let(:user) { User.new }
|
7
|
+
let(:project) { Project.new }
|
8
|
+
let(:issue) { Issue.new }
|
9
|
+
|
10
|
+
subject do
|
11
|
+
obj = NestedResourceUrl::NestedResource.new
|
12
|
+
obj << user
|
13
|
+
obj << project
|
14
|
+
obj << issue
|
15
|
+
obj
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should remove instances of symbol project' do
|
19
|
+
(subject - :project).should eq([user, issue])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should remove instances of symbol project through except' do
|
23
|
+
subject.except(:project).should eq([user, issue])
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should remove instances of symbol user and issue' do
|
27
|
+
(subject - [:user, :issue]).should eq([project])
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
it 'should keep everything but user by symbol' do
|
32
|
+
(subject & :user).should eq([user])
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should keep everything but user by symbol through only' do
|
36
|
+
subject.only(:user).should eq([user])
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should keep everything but project and issue by symbol' do
|
40
|
+
(subject & [:project, :issue]).should eq([project, issue])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should match an object in array by symbol' do
|
44
|
+
subject.send(:contains_type_of, project, [:project]).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should match an object in array by class' do
|
48
|
+
subject.send(:contains_type_of, issue, [Issue]).should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should match an object in array by instance' do
|
52
|
+
subject.send(:contains_type_of, issue, [issue]).should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return a symbol from object instance' do
|
56
|
+
subject.send(:resource_name, issue).should be(:issue)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
3
|
+
config.run_all_when_everything_filtered = true
|
4
|
+
config.filter_run :focus
|
5
|
+
|
6
|
+
config.order = 'random'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'nested_resource_url'
|
10
|
+
require 'helpers/receiver'
|
11
|
+
|
12
|
+
def setup_receiver!(configuration = {})
|
13
|
+
configuration = {
|
14
|
+
resource: :task,
|
15
|
+
object_names: [:user, :project],
|
16
|
+
options: {}
|
17
|
+
}.merge(configuration)
|
18
|
+
let(:method_definer) { NestedResourceUrl::MethodDefiner.new(Receiver) }
|
19
|
+
subject do
|
20
|
+
method_definer.define_methods!(configuration[:resource], configuration[:object_names], configuration[:options])
|
21
|
+
Receiver.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup_subject!(configuration = {})
|
26
|
+
configuration = {
|
27
|
+
nested_resources: [],
|
28
|
+
object_names: [:user, :project],
|
29
|
+
options: {}
|
30
|
+
}.merge(configuration)
|
31
|
+
subject.stub(:collect_nested_resource_objects){ configuration[:nested_resources] }
|
32
|
+
subject.should_receive(:collect_nested_resource_objects).with(configuration[:object_names], configuration[:options])
|
33
|
+
return subject
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nested_resource_url
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- menostos
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
description: The gem will add some helpers to controllers and view to automatically
|
31
|
+
create nested urls
|
32
|
+
email:
|
33
|
+
- menostos@gmail.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- .rspec
|
40
|
+
- Gemfile
|
41
|
+
- LICENSE.txt
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- lib/nested_resource_url.rb
|
45
|
+
- lib/nested_resource_url/collector.rb
|
46
|
+
- lib/nested_resource_url/helpers.rb
|
47
|
+
- lib/nested_resource_url/method_definer.rb
|
48
|
+
- lib/nested_resource_url/nested_resource.rb
|
49
|
+
- lib/nested_resource_url/version.rb
|
50
|
+
- nested_resource_url.gemspec
|
51
|
+
- spec/helper_spec.rb
|
52
|
+
- spec/helpers/receiver.rb
|
53
|
+
- spec/method_definer_call_merged_options_spec.rb
|
54
|
+
- spec/method_definer_call_spec.rb
|
55
|
+
- spec/method_definer_method_spec.rb
|
56
|
+
- spec/nested_resource_spec.rb
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
homepage: ''
|
59
|
+
licenses: []
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.8.24
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: nested url helper for controller and views
|
82
|
+
test_files:
|
83
|
+
- spec/helper_spec.rb
|
84
|
+
- spec/helpers/receiver.rb
|
85
|
+
- spec/method_definer_call_merged_options_spec.rb
|
86
|
+
- spec/method_definer_call_spec.rb
|
87
|
+
- spec/method_definer_method_spec.rb
|
88
|
+
- spec/nested_resource_spec.rb
|
89
|
+
- spec/spec_helper.rb
|