acts-as-taggable-on-dynamic 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.
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/Guardfile +5 -0
- data/LICENSE.md +20 -0
- data/README.md +76 -0
- data/Rakefile +10 -0
- data/acts-as-taggable-on-dynamic.gemspec +33 -0
- data/gemfiles/rails_3.gemfile +7 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/lib/acts-as-taggable-on-dynamic.rb +1 -0
- data/lib/acts_as_taggable_on_dynamic.rb +25 -0
- data/lib/acts_as_taggable_on_dynamic/dynamic_mass_assignment_authorizer.rb +16 -0
- data/lib/acts_as_taggable_on_dynamic/dynamic_tag_context_attributes.rb +88 -0
- data/lib/acts_as_taggable_on_dynamic/dynamic_tag_helpers.rb +29 -0
- data/lib/acts_as_taggable_on_dynamic/rails/engine.rb +8 -0
- data/lib/acts_as_taggable_on_dynamic/rails/version.rb +7 -0
- data/lib/acts_as_taggable_on_dynamic/taggable.rb +15 -0
- data/lib/acts_as_taggable_on_dynamic/utils.rb +21 -0
- data/lib/assets/javascripts/taggable.dynamic.js +59 -0
- data/spec/acts_as_taggable_on_dynamic_spec.rb +73 -0
- data/spec/database.yml.sample +3 -0
- data/spec/models.rb +3 -0
- data/spec/schema.rb +24 -0
- data/spec/spec_helper.rb +65 -0
- metadata +222 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
__Copyright (c) 2013 Dirk Eisenberg.__
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# ActsAsTaggableOnDynamic
|
2
|
+
This plugin is an extension to the amazing [acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on) plugin which allows to tag different models. The dynamic extension
|
3
|
+
allows to use the standard rails form generators and integrates dynamic contexts for the tags. It's nothing more needed than
|
4
|
+
adding some helpers into your form view. It's also using [handlebars](https://github.com/leshill/handlebars_assets) template for the javascript logic in the formular.
|
5
|
+
|
6
|
+
## Compatibility
|
7
|
+
|
8
|
+
Versions 0.0.x are compatible with Ruby 1.9.3 and Rails 3.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Ensure that act-as-taggable-on is installed and well configured. To use this plugin, add it to your Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'acts-as-taggable-on-dynamic'
|
16
|
+
```
|
17
|
+
|
18
|
+
and bundle:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
## Testing
|
25
|
+
|
26
|
+
Acts As Taggable On Dynamic uses RSpec for its test coverage. Inside the gem
|
27
|
+
directory, you can run the specs with:
|
28
|
+
|
29
|
+
```shell
|
30
|
+
bundle
|
31
|
+
rake spec
|
32
|
+
```
|
33
|
+
|
34
|
+
If you want, add a `.ruby-version` file in the project root (and use rbenv or RVM) to work on a specific version of Ruby.
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
Add our javascript which comes through the gem to the asset pipeline by adding the following line in the application.js file:
|
39
|
+
|
40
|
+
```javascript
|
41
|
+
//= require taggable.dynamic
|
42
|
+
```
|
43
|
+
|
44
|
+
Add dynamic tag context support to your existing form (normally _form)
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
<%= tag_context_form_template(@location) %>
|
48
|
+
<%= form_for(@location) do |f| %>
|
49
|
+
...
|
50
|
+
<%= tag_context_form(@location) %>
|
51
|
+
<%= tag_context_add(@location) %>
|
52
|
+
|
53
|
+
<div class="actions">
|
54
|
+
<%= f.submit %>
|
55
|
+
</div>
|
56
|
+
<% end %>
|
57
|
+
```
|
58
|
+
|
59
|
+
Add dynamic tag renderer to your details view (normally show.html.erb)
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
<% @location.tag_context_list.each do |context| %>
|
63
|
+
<p>
|
64
|
+
<b>Tags (Context - <%=context%>):</b>
|
65
|
+
<%= @location.tag_list_on(context)%>
|
66
|
+
</p>
|
67
|
+
<% end %>
|
68
|
+
```
|
69
|
+
|
70
|
+
## Maintainer
|
71
|
+
|
72
|
+
* [Dirk Eisenberg](https://github.com/dei79)
|
73
|
+
|
74
|
+
## License
|
75
|
+
|
76
|
+
See [LICENSE](https://github.com/dei79/acts-as-taggable-on-dynamic/blob/master/LICENSE.md)
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path('../lib/acts_as_taggable_on_dynamic/rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "acts-as-taggable-on-dynamic"
|
6
|
+
gem.version = ActsAsTaggableOnDynamic::Rails::VERSION
|
7
|
+
gem.authors = ["Dirk Eisenberg"]
|
8
|
+
gem.email = ["dirk.eisenberg@gmail.com"]
|
9
|
+
gem.description = %q{With ActsAsTaggableOnDynamic, you can tag a single model on several contexts based on the ActsAsTaggableOn gem. This gem extends rails forms support.}
|
10
|
+
gem.summary = "Advanced tagging for Rails with forms and dynamic tags."
|
11
|
+
gem.homepage = 'https://github.com/dei79/acts-as-taggable-on-dynamic'
|
12
|
+
gem.license = "MIT"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
if File.exists?('UPGRADING')
|
20
|
+
gem.post_install_message = File.read('UPGRADING')
|
21
|
+
end
|
22
|
+
|
23
|
+
gem.add_dependency "railties", "~> 3.1"
|
24
|
+
gem.add_runtime_dependency 'acts-as-taggable-on'
|
25
|
+
gem.add_runtime_dependency 'handlebars_assets'
|
26
|
+
gem.add_runtime_dependency 'inflection-js-rails'
|
27
|
+
|
28
|
+
gem.add_development_dependency 'rspec', '~> 2.6'
|
29
|
+
gem.add_development_dependency 'sqlite3'
|
30
|
+
gem.add_development_dependency 'mysql2', '~> 0.3.7'
|
31
|
+
gem.add_development_dependency 'guard'
|
32
|
+
gem.add_development_dependency 'guard-rspec'
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "acts_as_taggable_on_dynamic"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# load rails
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
# it's an engine
|
5
|
+
require 'acts_as_taggable_on_dynamic/rails/engine'
|
6
|
+
require 'acts_as_taggable_on_dynamic/rails/version'
|
7
|
+
|
8
|
+
# load the dependencies
|
9
|
+
require('acts-as-taggable-on')
|
10
|
+
|
11
|
+
# load our code
|
12
|
+
require('acts_as_taggable_on_dynamic/dynamic_mass_assignment_authorizer')
|
13
|
+
require('acts_as_taggable_on_dynamic/dynamic_tag_context_attributes')
|
14
|
+
require('acts_as_taggable_on_dynamic/dynamic_tag_helpers')
|
15
|
+
require('acts_as_taggable_on_dynamic/taggable')
|
16
|
+
require('acts_as_taggable_on_dynamic/utils')
|
17
|
+
|
18
|
+
# handle ActiveRecord stuff
|
19
|
+
if defined?(ActiveRecord::Base)
|
20
|
+
ActiveRecord::Base.extend ActsAsTaggableOnDynamic::Taggable
|
21
|
+
end
|
22
|
+
|
23
|
+
if defined?(ActionView::Base)
|
24
|
+
ActionView::Base.send :include, ActsAsTaggableOnDynamic::DynamicTagHelpers
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class ActsAsTaggableOnDynamic::DynamicMassAssignmentAuthorizer
|
2
|
+
|
3
|
+
def initialize(model, orgAuthorizer)
|
4
|
+
@model = model
|
5
|
+
@orgAuthorizer = orgAuthorizer
|
6
|
+
end
|
7
|
+
|
8
|
+
def deny?(key)
|
9
|
+
if (@model.dynamic_tag_context_attribute?(key) || @model.tag_list_attribute?(key))
|
10
|
+
false
|
11
|
+
else
|
12
|
+
@orgAuthorizer.deny?(key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module ActsAsTaggableOnDynamic
|
2
|
+
module DynamicTagContextAttributes
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :include, ActsAsTaggableOnDynamic::DynamicTagContextAttributes::InstanceMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
##
|
10
|
+
# Returns a text string which returns generates the list attribute given by the context name for taggings
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# self.dynamic_tag_context_attribute("skills") => "dynamic_tag_context_skill_list"
|
14
|
+
#
|
15
|
+
def dynamic_tag_context_attribute(context)
|
16
|
+
"dynamic_tag_context_#{context.singularize}_list"
|
17
|
+
end
|
18
|
+
|
19
|
+
def dynamic_tag_context_attribute_template()
|
20
|
+
"dynamic_tag_context_{{context}}_list"
|
21
|
+
end
|
22
|
+
|
23
|
+
def dynamic_tag_context_label_template()
|
24
|
+
"{{context}}"
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Validates if the given attribute is a dynamic context tag
|
29
|
+
#
|
30
|
+
def dynamic_tag_context_attribute?(attribute)
|
31
|
+
(attribute.to_s.start_with?('dynamic_tag_context_') && attribute.to_s.ends_with?('_list'))
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Returns the context of a give attributes name
|
36
|
+
#
|
37
|
+
def dynamic_tag_context_from_attribute(attribute)
|
38
|
+
attribute.to_s.sub('dynamic_tag_context_', '').chomp('_list').pluralize
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Validates if the given attribute is a tag list attribute
|
43
|
+
def tag_list_attribute?(attribute)
|
44
|
+
attribute.to_s.ends_with?('_list')
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Returns the contetn of a give tag list
|
49
|
+
#
|
50
|
+
def tag_list_content_on(context)
|
51
|
+
self.tags_on(context).map(&:to_s).join(',').chomp(',')
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Handles all read and write operations to a dynamic tag context
|
56
|
+
#
|
57
|
+
def method_missing(method_name, *args, &block)
|
58
|
+
|
59
|
+
attribute = method_name.to_s.chomp('=')
|
60
|
+
|
61
|
+
if ( dynamic_tag_context_attribute?(attribute) || tag_list_attribute?(attribute))
|
62
|
+
|
63
|
+
context = dynamic_tag_context_from_attribute(attribute).to_sym
|
64
|
+
|
65
|
+
if (method_name.to_s.ends_with?("="))
|
66
|
+
self.set_tag_list_on(context, args.join(',').chomp(','))
|
67
|
+
else
|
68
|
+
return tag_list_content_on(context)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Validates if the requested method a supported method
|
77
|
+
#
|
78
|
+
def respond_to?(method_name, include_private = false)
|
79
|
+
dynamic_tag_context_attribute?(method_name.to_s.chomp("=")) || tag_list_attribute?(method_name.to_s.chomp("=")) || super
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def mass_assignment_authorizer(role)
|
84
|
+
ActsAsTaggableOnDynamic::DynamicMassAssignmentAuthorizer.new(self, super(role))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ActsAsTaggableOnDynamic
|
2
|
+
module DynamicTagHelpers
|
3
|
+
def tag_context_form(model)
|
4
|
+
content_tag(:ul, :id => "#{model.class.name.downcase}_tag_context_form") do
|
5
|
+
model.tag_context_list.collect { |context| concat(content_tag(:li, "", { "data-model-type" => model.class.name.downcase, "data-context" => context, "data-value" => model.tag_list_content_on(context)})) }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def tag_context_form_template(model)
|
10
|
+
content_tag(:script, :id => "#{model.class.name.downcase}_new_context_form_template", :type => "text/x-handlebars-template") do
|
11
|
+
content_tag(:div, :class => :field) do
|
12
|
+
content_tag(:label, model.dynamic_tag_context_label_template, :for => "#{model.class.name.downcase}_#{model.dynamic_tag_context_attribute_template}") +
|
13
|
+
content_tag(:input, "",
|
14
|
+
:id => "#{model.class.name.downcase}_#{model.dynamic_tag_context_attribute_template}",
|
15
|
+
:name => "#{model.class.name.downcase}[#{model.dynamic_tag_context_attribute_template}]",
|
16
|
+
:value => "{{values}}",
|
17
|
+
:size => 30, :type => :text)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def tag_context_add(model, options = {})
|
23
|
+
content_tag(:div, :id => "act-as-taggable-dynamic-new_context_form") do
|
24
|
+
content_tag(:a, options[:label] ? options[:label] : "add context" , :href => "#") +
|
25
|
+
content_tag(:input, "", :name => "act-as-taggable-dynamic-new_context_form-input", :type => :text, "data-model-type" => model.class.name.downcase)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ActsAsTaggableOnDynamic
|
2
|
+
module Taggable
|
3
|
+
|
4
|
+
def acts_as_taggable_dynamic
|
5
|
+
# make the model taggable from the original gem
|
6
|
+
acts_as_taggable
|
7
|
+
|
8
|
+
# add the specific model methods we need
|
9
|
+
class_eval do
|
10
|
+
include ActsAsTaggableOnDynamic::Utils
|
11
|
+
include ActsAsTaggableOnDynamic::DynamicTagContextAttributes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActsAsTaggableOnDynamic
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :include, ActsAsTaggableOnDynamic::Utils::InstanceMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
|
10
|
+
##
|
11
|
+
# Return an array of context names which are valid for the given model type
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
# self.tag_context_list => ['tags']
|
15
|
+
#
|
16
|
+
def tag_context_list
|
17
|
+
ActsAsTaggableOn::Tagging.where("taggable_type = '#{self.class.name}'").select(:context).uniq.map(&:context)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
$(function() {
|
2
|
+
|
3
|
+
function getTemplateIdFromModelType(modeltype) {
|
4
|
+
return "#" + modeltype + "_new_context_form_template"
|
5
|
+
}
|
6
|
+
|
7
|
+
function applyContextTemplate(el) {
|
8
|
+
// build the template id
|
9
|
+
var templateId = getTemplateIdFromModelType($(el).attr("data-model-type"))
|
10
|
+
|
11
|
+
// get the context from the element
|
12
|
+
var context = $(el).attr("data-context")
|
13
|
+
|
14
|
+
// get the current value from the element
|
15
|
+
var values = $(el).attr("data-value")
|
16
|
+
|
17
|
+
// do it
|
18
|
+
createNewContextFormInListItem(el, templateId, context, values)
|
19
|
+
}
|
20
|
+
|
21
|
+
function createNewContextFormInListItem(el, fromTemplate, forContext, withValues) {
|
22
|
+
// load the template of the element
|
23
|
+
var source = $(fromTemplate).html();
|
24
|
+
|
25
|
+
// compile the template via handlebars
|
26
|
+
var template = Handlebars.compile(source);
|
27
|
+
|
28
|
+
// generate the data field
|
29
|
+
var data = { context: forContext, context_attribute: forContext.singularize(), values: withValues};
|
30
|
+
|
31
|
+
// attach the formular to the element
|
32
|
+
$(el).append(template(data))
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
$('li[data-context]').each(function(index, value) {
|
37
|
+
applyContextTemplate(value)
|
38
|
+
})
|
39
|
+
|
40
|
+
$('div#act-as-taggable-dynamic-new_context_form a').click(function() {
|
41
|
+
// get the value
|
42
|
+
var value = $('div#act-as-taggable-dynamic-new_context_form a').parent().find('input').val()
|
43
|
+
|
44
|
+
// get the model type
|
45
|
+
var modeltype = $('div#act-as-taggable-dynamic-new_context_form a').parent().find('input').attr('data-model-type')
|
46
|
+
|
47
|
+
// read out the model type
|
48
|
+
var templateId = getTemplateIdFromModelType(modeltype)
|
49
|
+
|
50
|
+
// find the list for this model type
|
51
|
+
var list = $("ul#" + modeltype + "_tag_context_form")
|
52
|
+
|
53
|
+
// create the list item we need
|
54
|
+
var listItem = $('<li></li>').appendTo(list)
|
55
|
+
|
56
|
+
// generate a new context
|
57
|
+
createNewContextFormInListItem(listItem , templateId, value, "")
|
58
|
+
})
|
59
|
+
})
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Location do
|
4
|
+
before(:each) do
|
5
|
+
@location = Location.new()
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:each) do
|
9
|
+
@location.destroy
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "dynamic_tag_context_attribute" do
|
13
|
+
it "should be generated by context name" do
|
14
|
+
@location.dynamic_tag_context_attribute("skills").should eql("dynamic_tag_context_skill_list")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be check a give attribute" do
|
18
|
+
@location.dynamic_tag_context_attribute?("dynamic_tag_context_skill_list").should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return the right context" do
|
22
|
+
@location.dynamic_tag_context_from_attribute("dynamic_tag_context_skill_list").should eql("skills")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "Dynamic Attributes Engine" do
|
27
|
+
|
28
|
+
it "should respond to dynamic_tag_context attributes" do
|
29
|
+
@location.respond_to?("dynamic_tag_context_skill_list=").should be_true
|
30
|
+
@location.respond_to?("dynamic_tag_context_skill_list").should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond to tag_list attributes" do
|
34
|
+
@location.respond_to?("skill_list").should be_true
|
35
|
+
@location.respond_to?("skill_list=").should be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should handle symbols as method_names correct" do
|
39
|
+
@location.respond_to?(:not_existing_attribute_symbol).should be_false
|
40
|
+
@location.respond_to?(:dynamic_tag_context_skill_list=).should be_true
|
41
|
+
@location.respond_to?(:dynamic_tag_context_skill_list).should be_true
|
42
|
+
@location.respond_to?(:skill_list).should be_true
|
43
|
+
@location.respond_to?(:skill_list=).should be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
it "should implement a valid tag setter" do
|
48
|
+
values = ["Value1", "Value2", "Value3"]
|
49
|
+
|
50
|
+
# skills
|
51
|
+
@location.dynamic_tag_context_skill_list= values
|
52
|
+
@location.save!
|
53
|
+
@location.dynamic_tag_context_skill_list.should eql(values.join(',').chomp(','))
|
54
|
+
@location.skill_list.should eql(values.join(',').chomp(','))
|
55
|
+
Location.tagged_with('Value1', :on => :skills).should include(@location)
|
56
|
+
|
57
|
+
# locations
|
58
|
+
@location.dynamic_tag_context_location_list= values
|
59
|
+
@location.save!
|
60
|
+
@location.dynamic_tag_context_location_list.should eql(values.join(',').chomp(','))
|
61
|
+
@location.location_list.should eql(values.join(',').chomp(','))
|
62
|
+
Location.tagged_with('Value1', :on => :locations).should include(@location)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "Mass Assignment Security" do
|
67
|
+
it "should authorizes dynamic tags" do
|
68
|
+
@location.mass_assignment_authorizer(:default).deny?("dynamic_tag_context_skill_list").should be_false
|
69
|
+
@location.mass_assignment_authorizer(:default).deny?("skill_list").should be_false
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/spec/models.rb
ADDED
data/spec/schema.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
ActiveRecord::Schema.define :version => 0 do
|
2
|
+
create_table "taggings", :force => true do |t|
|
3
|
+
t.integer "tag_id", :limit => 11
|
4
|
+
t.integer "taggable_id", :limit => 11
|
5
|
+
t.string "taggable_type"
|
6
|
+
t.string "context"
|
7
|
+
t.datetime "created_at"
|
8
|
+
t.integer "tagger_id", :limit => 11
|
9
|
+
t.string "tagger_type"
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
|
13
|
+
add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
|
14
|
+
|
15
|
+
create_table "tags", :force => true do |t|
|
16
|
+
t.string "name"
|
17
|
+
end
|
18
|
+
|
19
|
+
create_table :locations, :force => true do |t|
|
20
|
+
t.column :name, :string
|
21
|
+
t.column :type, :string
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
$LOAD_PATH << "." unless $LOAD_PATH.include?(".")
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "rubygems"
|
6
|
+
require "bundler"
|
7
|
+
|
8
|
+
if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.5")
|
9
|
+
raise RuntimeError, "Your bundler version is too old." +
|
10
|
+
"Run `gem install bundler` to upgrade."
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set up load paths for all bundled gems
|
14
|
+
Bundler.setup
|
15
|
+
rescue Bundler::GemNotFound
|
16
|
+
raise RuntimeError, "Bundler couldn't find some gems." +
|
17
|
+
"Did you run \`bundlee install\`?"
|
18
|
+
end
|
19
|
+
|
20
|
+
Bundler.require
|
21
|
+
require File.expand_path('../../lib/acts_as_taggable_on_dynamic', __FILE__)
|
22
|
+
|
23
|
+
# set adapter to use, default is sqlite3
|
24
|
+
# to use an alternative adapter run => rake spec DB='postgresql'
|
25
|
+
db_name = ENV['DB'] || 'sqlite3'
|
26
|
+
database_yml = File.expand_path('../database.yml', __FILE__)
|
27
|
+
|
28
|
+
if File.exists?(database_yml)
|
29
|
+
active_record_configuration = YAML.load_file(database_yml)
|
30
|
+
|
31
|
+
ActiveRecord::Base.configurations = active_record_configuration
|
32
|
+
config = ActiveRecord::Base.configurations[db_name]
|
33
|
+
|
34
|
+
begin
|
35
|
+
ActiveRecord::Base.establish_connection(db_name)
|
36
|
+
ActiveRecord::Base.connection
|
37
|
+
rescue
|
38
|
+
case db_name
|
39
|
+
when /mysql/
|
40
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
|
41
|
+
ActiveRecord::Base.connection.create_database(config['database'], {:charset => 'utf8', :collation => 'utf8_unicode_ci'})
|
42
|
+
when 'postgresql'
|
43
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
44
|
+
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => 'utf8'))
|
45
|
+
end
|
46
|
+
|
47
|
+
ActiveRecord::Base.establish_connection(config)
|
48
|
+
end
|
49
|
+
|
50
|
+
logger = ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
|
51
|
+
ActiveRecord::Base.default_timezone = :utc
|
52
|
+
|
53
|
+
begin
|
54
|
+
old_logger_level, logger.level = logger.level, ::Logger::ERROR
|
55
|
+
ActiveRecord::Migration.verbose = false
|
56
|
+
|
57
|
+
load(File.dirname(__FILE__) + '/schema.rb')
|
58
|
+
load(File.dirname(__FILE__) + '/models.rb')
|
59
|
+
ensure
|
60
|
+
logger.level = old_logger_level
|
61
|
+
end
|
62
|
+
|
63
|
+
else
|
64
|
+
raise "Please create #{database_yml} first to configure your database. Take a look at: #{database_yml}.sample"
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts-as-taggable-on-dynamic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dirk Eisenberg
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: railties
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.1'
|
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.1'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: acts-as-taggable-on
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: handlebars_assets
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: inflection-js-rails
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '2.6'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.6'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: sqlite3
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: mysql2
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.3.7
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.3.7
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: guard
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: guard-rspec
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: With ActsAsTaggableOnDynamic, you can tag a single model on several contexts
|
159
|
+
based on the ActsAsTaggableOn gem. This gem extends rails forms support.
|
160
|
+
email:
|
161
|
+
- dirk.eisenberg@gmail.com
|
162
|
+
executables: []
|
163
|
+
extensions: []
|
164
|
+
extra_rdoc_files: []
|
165
|
+
files:
|
166
|
+
- .gitignore
|
167
|
+
- .rspec
|
168
|
+
- .travis.yml
|
169
|
+
- Gemfile
|
170
|
+
- Guardfile
|
171
|
+
- LICENSE.md
|
172
|
+
- README.md
|
173
|
+
- Rakefile
|
174
|
+
- acts-as-taggable-on-dynamic.gemspec
|
175
|
+
- gemfiles/rails_3.gemfile
|
176
|
+
- gemfiles/rails_4.gemfile
|
177
|
+
- lib/acts-as-taggable-on-dynamic.rb
|
178
|
+
- lib/acts_as_taggable_on_dynamic.rb
|
179
|
+
- lib/acts_as_taggable_on_dynamic/dynamic_mass_assignment_authorizer.rb
|
180
|
+
- lib/acts_as_taggable_on_dynamic/dynamic_tag_context_attributes.rb
|
181
|
+
- lib/acts_as_taggable_on_dynamic/dynamic_tag_helpers.rb
|
182
|
+
- lib/acts_as_taggable_on_dynamic/rails/engine.rb
|
183
|
+
- lib/acts_as_taggable_on_dynamic/rails/version.rb
|
184
|
+
- lib/acts_as_taggable_on_dynamic/taggable.rb
|
185
|
+
- lib/acts_as_taggable_on_dynamic/utils.rb
|
186
|
+
- lib/assets/javascripts/taggable.dynamic.js
|
187
|
+
- spec/acts_as_taggable_on_dynamic_spec.rb
|
188
|
+
- spec/database.yml.sample
|
189
|
+
- spec/models.rb
|
190
|
+
- spec/schema.rb
|
191
|
+
- spec/spec_helper.rb
|
192
|
+
homepage: https://github.com/dei79/acts-as-taggable-on-dynamic
|
193
|
+
licenses:
|
194
|
+
- MIT
|
195
|
+
post_install_message:
|
196
|
+
rdoc_options: []
|
197
|
+
require_paths:
|
198
|
+
- lib
|
199
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
200
|
+
none: false
|
201
|
+
requirements:
|
202
|
+
- - ! '>='
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '0'
|
205
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
|
+
none: false
|
207
|
+
requirements:
|
208
|
+
- - ! '>='
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: '0'
|
211
|
+
requirements: []
|
212
|
+
rubyforge_project:
|
213
|
+
rubygems_version: 1.8.23
|
214
|
+
signing_key:
|
215
|
+
specification_version: 3
|
216
|
+
summary: Advanced tagging for Rails with forms and dynamic tags.
|
217
|
+
test_files:
|
218
|
+
- spec/acts_as_taggable_on_dynamic_spec.rb
|
219
|
+
- spec/database.yml.sample
|
220
|
+
- spec/models.rb
|
221
|
+
- spec/schema.rb
|
222
|
+
- spec/spec_helper.rb
|