Moved acts_as_configurable to gemfile.
This commit is contained in:
parent
7e6ac8c924
commit
ddcb4a9b2d
17 changed files with 10 additions and 922 deletions
1
Gemfile
1
Gemfile
|
@ -35,6 +35,7 @@ gem 'simple-navigation-bootstrap'
|
||||||
gem 'meta_search'
|
gem 'meta_search'
|
||||||
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git' # Use this instead of rubygem
|
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git' # Use this instead of rubygem
|
||||||
gem 'acts_as_tree'
|
gem 'acts_as_tree'
|
||||||
|
gem 'acts_as_configurable', git: 'git://github.com/bwalding/acts_as_configurable.git'
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
gem 'exception_notification', :require => 'exception_notifier'
|
gem 'exception_notification', :require => 'exception_notifier'
|
||||||
|
|
|
@ -4,6 +4,13 @@ GIT
|
||||||
specs:
|
specs:
|
||||||
localize_input (0.1.0)
|
localize_input (0.1.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/bwalding/acts_as_configurable.git
|
||||||
|
revision: cdf6f6f979019275b523d10684b748f08e2dd8e8
|
||||||
|
specs:
|
||||||
|
acts_as_configurable (0.0.1)
|
||||||
|
rake
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/technoweenie/acts_as_versioned.git
|
remote: git://github.com/technoweenie/acts_as_versioned.git
|
||||||
revision: 63b1fc8529d028fae632fe80ec0cb25df56cd76b
|
revision: 63b1fc8529d028fae632fe80ec0cb25df56cd76b
|
||||||
|
@ -189,6 +196,7 @@ PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
acts_as_configurable!
|
||||||
acts_as_tree
|
acts_as_tree
|
||||||
acts_as_versioned!
|
acts_as_versioned!
|
||||||
client_side_validations
|
client_side_validations
|
||||||
|
|
20
vendor/plugins/acts_as_configurable/MIT-LICENSE
vendored
20
vendor/plugins/acts_as_configurable/MIT-LICENSE
vendored
|
@ -1,20 +0,0 @@
|
||||||
Copyright (c) 2006 Jacob Radford
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
94
vendor/plugins/acts_as_configurable/README
vendored
94
vendor/plugins/acts_as_configurable/README
vendored
|
@ -1,94 +0,0 @@
|
||||||
= acts_as_configurable
|
|
||||||
|
|
||||||
This mixin adds a number of methods to an ActiveRecord module which
|
|
||||||
enable saving any settings you want (see examples below).
|
|
||||||
ActiveRecord is required.
|
|
||||||
|
|
||||||
== Install
|
|
||||||
|
|
||||||
./script/plugin install http://svn.nkryptic.com/plugins/acts_as_configurable
|
|
||||||
|
|
||||||
== Usage
|
|
||||||
|
|
||||||
This mixin will provide your model with a large variety of configuration options.
|
|
||||||
class User < ActiveRecord::Base
|
|
||||||
acts_as_configurable
|
|
||||||
end
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
user = User.create(:name => 'joe')
|
|
||||||
user.settings # => []
|
|
||||||
|
|
||||||
user.settings[:friends] = ['jane','sam','karl']
|
|
||||||
user.settings[:friends] # => ['jane','sam','karl']
|
|
||||||
user.settings[:age] = 25
|
|
||||||
user.settings[:age] # => 25
|
|
||||||
|
|
||||||
OR
|
|
||||||
|
|
||||||
user = User.create(:name => 'joe')
|
|
||||||
post = Post.find(:first)
|
|
||||||
|
|
||||||
user.settings_for(post) # => []
|
|
||||||
user.settings_for(post)[:show_headlines] = true
|
|
||||||
|
|
||||||
user.settings_for(post)[:show_headlines] # => true
|
|
||||||
user.settings_for(post).size # => 1
|
|
||||||
|
|
||||||
# but the user's untargeted settings are still empty
|
|
||||||
user.settings # => []
|
|
||||||
|
|
||||||
update: now there is a method each_with_key
|
|
||||||
user.settings.each_with_key {|k,s| do something} # k is the key (a string) and s is the setting
|
|
||||||
and
|
|
||||||
user.settings_for(post).each_with_key {|k,s| do something} # k is the key (a string) and s is the setting
|
|
||||||
|
|
||||||
|
|
||||||
This mixin will provide your model with the ability to see where it is used as a target of acts_as_configurable
|
|
||||||
class Post < ActiveRecord::Base
|
|
||||||
acts_as_configurable_target
|
|
||||||
end
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
user = User.create(:name => 'joe')
|
|
||||||
post = Post.find(:first)
|
|
||||||
|
|
||||||
user.settings_for(post) # => []
|
|
||||||
user.settings_for(post)[:num_lines] = 15
|
|
||||||
|
|
||||||
user.settings_for(post)[:num_lines] # => 15
|
|
||||||
post.targeted_settings[:num_lines].size # => 1
|
|
||||||
post.targeted_settings[:num_lines].first # => 15
|
|
||||||
post.targeted_settings[:num_lines].first.owner # => user
|
|
||||||
|
|
||||||
OR
|
|
||||||
|
|
||||||
user = User.create(:name => 'joe')
|
|
||||||
post = Post.find(:first)
|
|
||||||
|
|
||||||
user.settings_for(post) # => []
|
|
||||||
user.settings_for(post)[:num_lines] = 15
|
|
||||||
|
|
||||||
user.settings_for(post)[:num_lines] # => 15
|
|
||||||
user.settings_for(post)[:hide_comments] # => true
|
|
||||||
post.targeted_settings_for(user)[:num_lines] # => 15
|
|
||||||
post.targeted_settings_for(user) # => [15,true]
|
|
||||||
post.targeted_settings_for(user).collect {|x| x.name} # => ['num_lines','hide_comments']
|
|
||||||
|
|
||||||
== Subversion
|
|
||||||
|
|
||||||
http://svn.nkryptic.com/plugins/acts_as_configurable
|
|
||||||
|
|
||||||
== Credits
|
|
||||||
|
|
||||||
I was insprired by the following people/works
|
|
||||||
|
|
||||||
* Rick Olson - acts_as_versioned plugin (plugin design)
|
|
||||||
* Bill Katz - authorization plugin (roles applied to any model)
|
|
||||||
* Tobias Luetke - Typo (configuration settings manager with ruby-typing of value)
|
|
||||||
* Rails core - AssociationCollection and AssociationProxy classes
|
|
||||||
|
|
||||||
|
|
||||||
|
|
22
vendor/plugins/acts_as_configurable/Rakefile
vendored
22
vendor/plugins/acts_as_configurable/Rakefile
vendored
|
@ -1,22 +0,0 @@
|
||||||
require 'rake'
|
|
||||||
require 'rake/testtask'
|
|
||||||
require 'rake/rdoctask'
|
|
||||||
|
|
||||||
desc 'Default: run unit tests.'
|
|
||||||
task :default => :test
|
|
||||||
|
|
||||||
desc 'Test the acts_as_configurable plugin.'
|
|
||||||
Rake::TestTask.new(:test) do |t|
|
|
||||||
t.libs << 'lib'
|
|
||||||
t.pattern = 'test/**/*_test.rb'
|
|
||||||
t.verbose = true
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Generate documentation for the acts_as_configurable plugin.'
|
|
||||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
||||||
rdoc.rdoc_dir = 'rdoc'
|
|
||||||
rdoc.title = 'ActsAsConfigurable'
|
|
||||||
rdoc.options << '--line-numbers' << '--inline-source'
|
|
||||||
rdoc.rdoc_files.include('README')
|
|
||||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
||||||
end
|
|
5
vendor/plugins/acts_as_configurable/init.rb
vendored
5
vendor/plugins/acts_as_configurable/init.rb
vendored
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
require 'acts_as_configurable'
|
|
||||||
ActiveRecord::Base.send(:include, Nkryptic::ActsAsConfigurable)
|
|
||||||
|
|
||||||
require 'configurable_setting'
|
|
|
@ -1 +0,0 @@
|
||||||
puts IO.read(File.join(File.dirname(__FILE__), 'README'))
|
|
|
@ -1,497 +0,0 @@
|
||||||
|
|
||||||
module Nkryptic # :nodoc:
|
|
||||||
module ActsAsConfigurable #:nodoc:
|
|
||||||
def self.included(base) # :nodoc:
|
|
||||||
base.extend ClassMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
# These methods will be available to any ActiveRecord::Base descended model.
|
|
||||||
module ClassMethods
|
|
||||||
|
|
||||||
# == Acts As Configurable
|
|
||||||
# requirements::
|
|
||||||
# model descended from ActiveRecord::Base
|
|
||||||
# configurable_settings table has been created
|
|
||||||
#
|
|
||||||
# class User < ActiveRecord::Base
|
|
||||||
# acts_as_configurable
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# This mixin will provide your model with a large variety of configuration options.
|
|
||||||
#
|
|
||||||
# see:: settings and settins_for
|
|
||||||
#
|
|
||||||
def acts_as_configurable(options = {})
|
|
||||||
|
|
||||||
# don't allow multiple calls
|
|
||||||
return if self.included_modules.include?(Nkryptic::ActsAsConfigurable::InstanceMethods)
|
|
||||||
send :include, Nkryptic::ActsAsConfigurable::InstanceMethods
|
|
||||||
|
|
||||||
cattr_accessor :defaults
|
|
||||||
self.defaults = (options.class == Hash ? options : {}).with_indifferent_access
|
|
||||||
|
|
||||||
has_many :_configurable_settings,
|
|
||||||
:as => :configurable,
|
|
||||||
:class_name => 'ConfigurableSetting',
|
|
||||||
:dependent => :destroy
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# == Acts As Configurable Target
|
|
||||||
# requirements::
|
|
||||||
# model descended from ActiveRecord::Base
|
|
||||||
# configurable_settings table has been created
|
|
||||||
#
|
|
||||||
# class User < ActiveRecord::Base
|
|
||||||
# acts_as_configurable_target
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# This mixin will provide your model with the ability to see where it is used as a target of acts_as_configurable
|
|
||||||
#
|
|
||||||
# see:: targetable_settings and targetable_settings_for
|
|
||||||
#
|
|
||||||
def acts_as_configurable_target(options = {})
|
|
||||||
return if self.included_modules.include?(Nkryptic::ActsAsConfigurable::TargetInstanceMethods)
|
|
||||||
send :include, Nkryptic::ActsAsConfigurable::TargetInstanceMethods
|
|
||||||
|
|
||||||
has_many :_targetable_settings,
|
|
||||||
:as => :targetable,
|
|
||||||
:class_name => 'ConfigurableSetting',
|
|
||||||
:dependent => :destroy
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
|
|
||||||
def self.included(base) # :nodoc:
|
|
||||||
base.extend Nkryptic::ActsAsConfigurable::InstanceMethods::ClassMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
# * specify any setting you want for an instance of a model
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# user = User.create(:name => 'joe')
|
|
||||||
# user.settings # => []
|
|
||||||
#
|
|
||||||
# user.settings[:friends] = ['jane','sam','karl']
|
|
||||||
# user.settings[:friends] # => ['jane','sam','karl']
|
|
||||||
# user.settings[:age] = 25
|
|
||||||
# user.settings[:age] # => 25
|
|
||||||
#
|
|
||||||
def settings
|
|
||||||
@general_settings ||= ConfigurableSettings.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
# * specify any setting you want for an instance of a model targeting another object
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# user = User.create(:name => 'joe')
|
|
||||||
# post = Post.find(:first)
|
|
||||||
#
|
|
||||||
# user.settings_for(post) # => []
|
|
||||||
# user.settings_for(post)[:show_headlines] = true
|
|
||||||
#
|
|
||||||
# user.settings_for(post)[:show_headlines] # => true
|
|
||||||
# user.settings_for(post).size # => 1
|
|
||||||
#
|
|
||||||
# # but the user's untargeted settings are still empty
|
|
||||||
# user.settings # => []
|
|
||||||
#
|
|
||||||
def settings_for(obj)
|
|
||||||
if obj.is_a? Class
|
|
||||||
# wire the settings object to only deal with settings targeting this class obj
|
|
||||||
variable_name = "settings_for_class_#{obj.name}"
|
|
||||||
else
|
|
||||||
# wire the settings object to only deal with settings targeting this instance obj
|
|
||||||
variable_name = "settings_for_#{obj.class}_#{obj.id}"
|
|
||||||
end
|
|
||||||
settings_obj = instance_variable_get("@#{variable_name}")
|
|
||||||
settings_obj = instance_variable_set("@#{variable_name}",ConfigurableSettings.new(self, obj)) if settings_obj.nil?
|
|
||||||
settings_obj
|
|
||||||
end
|
|
||||||
|
|
||||||
# These are class methods that are mixed in with the model class.
|
|
||||||
module ClassMethods # :nodoc:
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module TargetInstanceMethods
|
|
||||||
|
|
||||||
def self.included(base) # :nodoc:
|
|
||||||
base.extend Nkryptic::ActsAsConfigurable::TargetInstanceMethods::ClassMethods
|
|
||||||
end
|
|
||||||
|
|
||||||
# * specify any setting you want for an instance of a model targeting another object
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# user = User.create(:name => 'joe')
|
|
||||||
# post = Post.find(:first)
|
|
||||||
#
|
|
||||||
# user.settings_for(post) # => []
|
|
||||||
# user.settings_for(post)[:num_lines] = 15
|
|
||||||
#
|
|
||||||
# user.settings_for(post)[:num_lines] # => 15
|
|
||||||
# post.targeted_settings[:num_lines].size # => 1
|
|
||||||
# post.targeted_settings[:num_lines].first # => 15
|
|
||||||
# post.targeted_settings[:num_lines].first.owner # => user
|
|
||||||
#
|
|
||||||
def targeted_settings
|
|
||||||
@targeted_settings ||= TargetedSettings.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
# * specify any setting you want for an instance of a model targeting another object
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# user = User.create(:name => 'joe')
|
|
||||||
# post = Post.find(:first)
|
|
||||||
#
|
|
||||||
# user.settings_for(post) # => []
|
|
||||||
# user.settings_for(post)[:num_lines] = 15
|
|
||||||
#
|
|
||||||
# user.settings_for(post)[:num_lines] # => 15
|
|
||||||
# user.settings_for(post)[:hide_comments] # => true
|
|
||||||
# post.targeted_settings_for(user)[:num_lines] # => 15
|
|
||||||
# post.targeted_settings_for(user) # => [15,true]
|
|
||||||
# post.targeted_settings_for(user).collect {|x| x.name} # => ['num_lines','hide_comments']
|
|
||||||
#
|
|
||||||
def targeted_settings_for(obj)
|
|
||||||
if obj.is_a? Class
|
|
||||||
# wire the targeted_settings object to only deal with settings targeting this class obj
|
|
||||||
variable_name = "targeted_settings_for_class_#{obj.name}"
|
|
||||||
else
|
|
||||||
# wire the targeted_settings object to only deal with settings targeting this instance obj
|
|
||||||
variable_name = "targeted_settings_for_#{obj.class}_#{obj.id}"
|
|
||||||
end
|
|
||||||
settings_obj = instance_variable_get("@#{variable_name}")
|
|
||||||
settings_obj = instance_variable_set("@#{variable_name}",TargetedSettings.new(self, obj)) if settings_obj.nil?
|
|
||||||
settings_obj
|
|
||||||
end
|
|
||||||
|
|
||||||
# These are class methods that are mixed in with the model class.
|
|
||||||
module ClassMethods # :nodoc:
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class ProxySettings # :nodoc:
|
|
||||||
alias_method '__class', 'class'
|
|
||||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$)/ }
|
|
||||||
|
|
||||||
#class_inheritable_accessor(:sql_word)
|
|
||||||
|
|
||||||
def initialize(source, reference=nil)
|
|
||||||
@source = source
|
|
||||||
@reference = reference
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def real_class
|
|
||||||
__class
|
|
||||||
end
|
|
||||||
|
|
||||||
def settings
|
|
||||||
@source.send(@settings)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_ary
|
|
||||||
find_settings.collect do |x|
|
|
||||||
ProxySetting.new(x)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def responds_to?(what)
|
|
||||||
settings.responds_to?(what)
|
|
||||||
end
|
|
||||||
|
|
||||||
def ==(what)
|
|
||||||
find_settings == what
|
|
||||||
end
|
|
||||||
|
|
||||||
def size
|
|
||||||
find_settings.size
|
|
||||||
end
|
|
||||||
|
|
||||||
def inspect
|
|
||||||
find_settings.inspect
|
|
||||||
end
|
|
||||||
|
|
||||||
def each(&block)
|
|
||||||
find_settings.each do |x|
|
|
||||||
yield ProxySetting.new(x)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def each_with_key(&block)
|
|
||||||
find_settings.each do |x|
|
|
||||||
yield(x.name, ProxySetting.new(x))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def select(&block)
|
|
||||||
find_settings.select do |x|
|
|
||||||
yield ProxySetting.new(x)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def reject(&block)
|
|
||||||
find_settings.reject do |x|
|
|
||||||
yield ProxySetting.new(x)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def collect(&block)
|
|
||||||
find_settings.collect do |x|
|
|
||||||
yield ProxySetting.new(x)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_key?(name)
|
|
||||||
name = name.to_s
|
|
||||||
setting = find_setting(name)
|
|
||||||
if setting.nil?
|
|
||||||
false
|
|
||||||
else
|
|
||||||
if setting.is_a? Array
|
|
||||||
setting.size == 0 ? false : true
|
|
||||||
else
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def [](name)
|
|
||||||
name = name.to_s
|
|
||||||
setting = find_setting(name)
|
|
||||||
return nil if setting.nil?
|
|
||||||
if setting.is_a? Array
|
|
||||||
setting.collect {|x| ProxySetting.new(x)}
|
|
||||||
else
|
|
||||||
ProxySetting.new(setting)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def []=(name, value)
|
|
||||||
name = name.to_s
|
|
||||||
setting = find_setting(name)
|
|
||||||
if setting.is_a? Array
|
|
||||||
setting.collect do |x|
|
|
||||||
x.value_type = value.class.to_s
|
|
||||||
x.value = value.to_yaml
|
|
||||||
x.save
|
|
||||||
ProxySetting.new(x)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if setting.nil?
|
|
||||||
setting = create_setting(name)
|
|
||||||
end
|
|
||||||
setting.value_type = value.class.to_s
|
|
||||||
setting.value = value.to_yaml
|
|
||||||
setting.save
|
|
||||||
ProxySetting.new(setting)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_settings; nil end
|
|
||||||
|
|
||||||
def find_setting(name); nil end
|
|
||||||
|
|
||||||
def create_setting(name); nil end
|
|
||||||
|
|
||||||
def method_missing(method, *args, &block)
|
|
||||||
settings.send(method, *args, &block)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
class ConfigurableSettings < ProxySettings # :nodoc:
|
|
||||||
|
|
||||||
def initialize(source, reference=nil)
|
|
||||||
super
|
|
||||||
@settings = '_configurable_settings'
|
|
||||||
@@sql_word = "targetable"
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_settings
|
|
||||||
if @reference.is_a? Class
|
|
||||||
settings.find( :all,
|
|
||||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", @reference.to_s ] )
|
|
||||||
elsif @reference
|
|
||||||
settings.find( :all,
|
|
||||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id = ?", @reference.class.to_s, @reference.id ] )
|
|
||||||
else
|
|
||||||
settings.find( :all,
|
|
||||||
:conditions => [ "#{@@sql_word}_type is null and #{@@sql_word}_id is null" ] )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_setting(name)
|
|
||||||
if @reference.is_a? Class
|
|
||||||
settings.find( :first,
|
|
||||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", name, @reference.to_s ] )
|
|
||||||
elsif @reference
|
|
||||||
settings.find( :first,
|
|
||||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id = ?", name, @reference.class.to_s, @reference.id ] )
|
|
||||||
else
|
|
||||||
settings.find( :first,
|
|
||||||
:conditions => [ "name = ? and #{@@sql_word}_type is null and #{@@sql_word}_id is null", name ] )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_setting(name)
|
|
||||||
if @reference.is_a? Class
|
|
||||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.to_s )
|
|
||||||
elsif @reference
|
|
||||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.class.to_s, "#{@@sql_word}_id" => @reference.id )
|
|
||||||
else
|
|
||||||
settings.create( :name => name )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
class TargetedSettings < ProxySettings # :nodoc:
|
|
||||||
|
|
||||||
def initialize(target, owner=nil)
|
|
||||||
super
|
|
||||||
@settings = '_targetable_settings'
|
|
||||||
@@sql_word = "configurable"
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def find_settings
|
|
||||||
if @reference.is_a? Class
|
|
||||||
settings.find( :all,
|
|
||||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", @reference.to_s ] )
|
|
||||||
elsif @reference
|
|
||||||
settings.find( :all,
|
|
||||||
:conditions => [ "#{@@sql_word}_type = ? and #{@@sql_word}_id = ?", @reference.class.to_s, @reference.id ] )
|
|
||||||
else
|
|
||||||
settings.find( :all )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_setting(name)
|
|
||||||
if @reference.is_a? Class
|
|
||||||
settings.find( :first,
|
|
||||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id IS NULL", name, @reference.to_s ] )
|
|
||||||
elsif @reference
|
|
||||||
settings.find( :first,
|
|
||||||
:conditions => [ "name = ? and #{@@sql_word}_type = ? and #{@@sql_word}_id = ?", name, @reference.class.to_s, @reference.id ] )
|
|
||||||
else
|
|
||||||
settings.find( :all,
|
|
||||||
:conditions => [ "name = ?", name ] )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_setting(name)
|
|
||||||
if @reference.is_a? Class
|
|
||||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.to_s )
|
|
||||||
elsif @reference
|
|
||||||
settings.create( :name => name, "#{@@sql_word}_type" => @reference.class.to_s, "#{@@sql_word}_id" => @reference.id )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
class ProxySetting # :nodoc:
|
|
||||||
|
|
||||||
alias_method '__class', 'class'
|
|
||||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$)/ }
|
|
||||||
|
|
||||||
def initialize(setting)
|
|
||||||
@_setting = setting
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def real_class
|
|
||||||
ProxySetting
|
|
||||||
end
|
|
||||||
|
|
||||||
def target
|
|
||||||
unless @_setting.targetable_type.blank? or @_setting.targetable_id.blank?
|
|
||||||
ConfigurableSetting.find_targetable(@_setting.targetable_type, @_setting.targetable_id)
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def owner
|
|
||||||
unless @_setting.configurable_type.blank? or @_setting.configurable_id.blank?
|
|
||||||
ConfigurableSetting.find_configurable(@_setting.configurable_type, @_setting.configurable_id)
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def []=(name, val)
|
|
||||||
obj = self.value
|
|
||||||
if obj.responds_to? '[]='
|
|
||||||
obj[name] = val
|
|
||||||
self.value = obj
|
|
||||||
self.save
|
|
||||||
else
|
|
||||||
method_missing('[]=', [name,val])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete(name)
|
|
||||||
obj = self.value
|
|
||||||
if obj.responds_to? 'delete'
|
|
||||||
obj.delete(name)
|
|
||||||
self.value = obj
|
|
||||||
self.save
|
|
||||||
else
|
|
||||||
method_missing('delete', [name,val])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def save
|
|
||||||
@_setting.save
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def value
|
|
||||||
@value ||= YAML.load(@_setting.value)
|
|
||||||
end
|
|
||||||
|
|
||||||
def value=(val)
|
|
||||||
@value = val
|
|
||||||
self.set_value
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_value
|
|
||||||
@_setting.value_type = @value.class.to_s
|
|
||||||
@_setting.value = @value.to_yaml
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def method_missing(method, *args, &block)
|
|
||||||
return_value = self.value.send(method, *args, &block)
|
|
||||||
if @value != YAML.load(@_setting.value)
|
|
||||||
STDERR.puts "#{method} called with args #{args} for ProxySetting"
|
|
||||||
self.set_value
|
|
||||||
end
|
|
||||||
return_value
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,50 +0,0 @@
|
||||||
# this is the base class of all configurable settings
|
|
||||||
class ConfigurableSetting < ActiveRecord::Base
|
|
||||||
belongs_to :configurable, :polymorphic => true
|
|
||||||
belongs_to :targetable, :polymorphic => true
|
|
||||||
|
|
||||||
# ==For migration up
|
|
||||||
# in your migration self.up method:
|
|
||||||
# <tt>ConfigurableSetting.create_table</tt>
|
|
||||||
def self.create_table
|
|
||||||
self.connection.create_table :configurable_settings, :options => 'ENGINE=InnoDB' do |t|
|
|
||||||
t.column :configurable_id, :integer
|
|
||||||
t.column :configurable_type, :string
|
|
||||||
t.column :targetable_id, :integer
|
|
||||||
t.column :targetable_type, :string
|
|
||||||
t.column :name, :string, :null => false
|
|
||||||
t.column :value_type, :string
|
|
||||||
t.column :value, :text, :null => true
|
|
||||||
end
|
|
||||||
self.connection.add_index :configurable_settings, :name
|
|
||||||
end
|
|
||||||
|
|
||||||
# ==For migration down
|
|
||||||
# in your migration self.down method:
|
|
||||||
# <tt>ConfigurableSetting.drop_table</tt>
|
|
||||||
def self.drop_table
|
|
||||||
self.connection.remove_index :configurable_settings, :name
|
|
||||||
self.connection.drop_table :configurable_settings
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns a string with the classname of configurable
|
|
||||||
def self.configurable_class(configurable) # :nodoc:
|
|
||||||
ActiveRecord::Base.send(:class_name_of_active_record_descendant, configurable.class).to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns a string with the classname of configurable
|
|
||||||
def self.targetable_class(targetable) # :nodoc:
|
|
||||||
ActiveRecord::Base.send(:class_name_of_active_record_descendant, targetable.class).to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns the instance of the "owner" of the setting
|
|
||||||
def self.find_configurable(configured_class, configured_id) # :nodoc:
|
|
||||||
configured_class.constantize.find(configured_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns the instance of the "target" of the setting
|
|
||||||
def self.find_targetable(targeted_class, targeted_id) # :nodoc:
|
|
||||||
targeted_class.constantize.find(targeted_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,28 +0,0 @@
|
||||||
require 'rake/testtask'
|
|
||||||
require 'rake/rdoctask'
|
|
||||||
|
|
||||||
namespace :test do
|
|
||||||
desc "run the acts as configurable test suite"
|
|
||||||
task :acts_as_configurable do
|
|
||||||
Rake::TestTask.new(:aac_test) do |t|
|
|
||||||
t.libs << File.join(File.dirname(__FILE__), '/../lib')
|
|
||||||
t.pattern = File.join(File.dirname(__FILE__), '/../test/**/*_test.rb')
|
|
||||||
t.verbose = true
|
|
||||||
end
|
|
||||||
Rake::Task[:aac_test].invoke
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
namespace :doc do
|
|
||||||
desc "generate the acts as configurable rdoc files"
|
|
||||||
task :acts_as_configurable do
|
|
||||||
Rake::RDocTask.new(:aac_rdoc) do |rdoc|
|
|
||||||
rdoc.rdoc_dir = File.join(File.dirname(__FILE__), '/../rdoc')
|
|
||||||
rdoc.title = 'Acts As Configurable'
|
|
||||||
rdoc.options << '--line-numbers' << '--inline-source'
|
|
||||||
rdoc.rdoc_files.include(File.join(File.dirname(__FILE__), '/../README'))
|
|
||||||
rdoc.rdoc_files.include(File.join(File.dirname(__FILE__), '/../lib/**/*.rb'))
|
|
||||||
end
|
|
||||||
Rake::Task[:aac_rdoc].invoke
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,117 +0,0 @@
|
||||||
require 'test/unit'
|
|
||||||
require File.dirname(__FILE__) + '/test_helper'
|
|
||||||
require File.join(File.dirname(__FILE__), 'fixtures/entities')
|
|
||||||
|
|
||||||
|
|
||||||
class ActsAsConfigurableTest < Test::Unit::TestCase
|
|
||||||
fixtures :test_users, :test_groups
|
|
||||||
|
|
||||||
def setup
|
|
||||||
@group = TestGroup.create(:display_name => 'Rails Core')
|
|
||||||
@user = TestUser.create(:login => 'sam', :name => 'Sam Testuser', :email => 'sam@example.com')
|
|
||||||
end
|
|
||||||
|
|
||||||
SETTINGS = ActiveRecord::Base.const_get('ConfigurableSettings')
|
|
||||||
TARGETEDSETTINGS = ActiveRecord::Base.const_get('TargetedSettings')
|
|
||||||
PROXYSETTING = ActiveRecord::Base.const_get('ProxySetting')
|
|
||||||
USR_CFG = {
|
|
||||||
:how_many_time_i_eat_out_a_week => 4,
|
|
||||||
'what i am made of' => 'steel',
|
|
||||||
:friends => ['bob', 'ken']
|
|
||||||
}
|
|
||||||
GR_ROLES = ['creator', 'member', 'fundraiser']
|
|
||||||
|
|
||||||
def test_user_model_settings
|
|
||||||
|
|
||||||
assert_equal 'sam', @user.login
|
|
||||||
assert_equal 'Rails Core', @group.display_name
|
|
||||||
|
|
||||||
assert_equal 0, @user._configurable_settings.size
|
|
||||||
assert_equal Array, @user.settings.class
|
|
||||||
assert_equal SETTINGS, @user.settings.real_class
|
|
||||||
assert_equal 0, @user.settings.size
|
|
||||||
|
|
||||||
@user.settings[:config] = USR_CFG
|
|
||||||
|
|
||||||
assert_equal 1, @user._configurable_settings.size
|
|
||||||
assert_equal USR_CFG, @user.settings[:config]
|
|
||||||
assert_equal 1, @user.settings.size
|
|
||||||
assert_equal Hash, @user.settings[:config].class
|
|
||||||
assert_equal PROXYSETTING, @user.settings[:config].real_class
|
|
||||||
assert_equal 3, @user.settings[:config].keys.size
|
|
||||||
assert_equal 4, @user.settings[:config][:how_many_time_i_eat_out_a_week]
|
|
||||||
assert_equal Array, @user.settings[:config][:friends].class
|
|
||||||
assert_equal 2, @user.settings[:config][:friends].size
|
|
||||||
|
|
||||||
@user.settings[:my_group] = @group
|
|
||||||
|
|
||||||
assert_equal 2, @user.settings.size
|
|
||||||
assert_equal TestGroup, @user.settings[:my_group].class
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_new_each_with_key
|
|
||||||
@user.settings[:config] = USR_CFG
|
|
||||||
@user.settings.each_with_key do |key, setting|
|
|
||||||
assert_equal :config.to_s, key
|
|
||||||
assert_equal USR_CFG, setting
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def test_valid_raw_setting
|
|
||||||
|
|
||||||
assert ConfigurableSetting.find(:first).nil?
|
|
||||||
|
|
||||||
@user.settings[:config] = USR_CFG
|
|
||||||
|
|
||||||
first_setting = ConfigurableSetting.find(:first)
|
|
||||||
|
|
||||||
assert_equal 'config', first_setting.name
|
|
||||||
assert_equal 'TestUser', first_setting.configurable_type
|
|
||||||
assert_equal @user.id, first_setting.configurable_id
|
|
||||||
assert_equal nil, first_setting.targetable_type
|
|
||||||
assert_equal nil, first_setting.targetable_id
|
|
||||||
assert_equal USR_CFG.to_yaml, first_setting.value
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def test_associated_settings
|
|
||||||
|
|
||||||
assert_equal [], @user.settings
|
|
||||||
assert_equal [], @user.settings_for(@group)
|
|
||||||
|
|
||||||
@user.settings_for(@group)[:roles] = GR_ROLES
|
|
||||||
|
|
||||||
assert_equal GR_ROLES, @user.settings_for(@group)[:roles]
|
|
||||||
assert_equal 1, @user.settings_for(@group).size
|
|
||||||
assert_equal 0, @user.settings.size
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def test_associated_target_settings
|
|
||||||
|
|
||||||
assert_equal [], @group.targeted_settings
|
|
||||||
assert_equal TARGETEDSETTINGS, @group.targeted_settings.real_class
|
|
||||||
|
|
||||||
@user.settings_for(@group)[:roles] = GR_ROLES
|
|
||||||
|
|
||||||
assert_equal 1, @group._targetable_settings.size
|
|
||||||
assert_equal 1, @group.targeted_settings.size
|
|
||||||
assert_equal 1, @group.targeted_settings_for(@user).size
|
|
||||||
assert_equal GR_ROLES, @group.targeted_settings_for(@user)[:roles]
|
|
||||||
@group.targeted_settings.each do |x|
|
|
||||||
assert x.owner == @user and x.target == @group and x.name == 'roles'
|
|
||||||
end
|
|
||||||
@group.targeted_settings.each do |x|
|
|
||||||
assert x == GR_ROLES
|
|
||||||
end
|
|
||||||
@group.targeted_settings[:roles].each do |x|
|
|
||||||
assert x.owner == @user and x == GR_ROLES
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,14 +0,0 @@
|
||||||
class TestUser < ActiveRecord::Base
|
|
||||||
|
|
||||||
acts_as_configurable
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestGroup < ActiveRecord::Base
|
|
||||||
|
|
||||||
acts_as_configurable
|
|
||||||
acts_as_configurable_target
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,4 +0,0 @@
|
||||||
---
|
|
||||||
test_groups_001:
|
|
||||||
id: "1"
|
|
||||||
display_name: Clan of the Cavebear
|
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
test_users_001:
|
|
||||||
name: Bob Testuser
|
|
||||||
id: "1"
|
|
||||||
login: bob
|
|
||||||
email: bob@example.com
|
|
||||||
test_users_002:
|
|
||||||
name: Ken Testuser
|
|
||||||
id: "2"
|
|
||||||
login: ken
|
|
||||||
email: ken@example.com
|
|
|
@ -1,28 +0,0 @@
|
||||||
ActiveRecord::Migration.verbose = false
|
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 0) do
|
|
||||||
|
|
||||||
create_table :configurable_settings, :force => true do |t|
|
|
||||||
t.column :configurable_id, :integer
|
|
||||||
t.column :configurable_type, :string
|
|
||||||
t.column :targetable_id, :integer
|
|
||||||
t.column :targetable_type, :string
|
|
||||||
t.column :name, :string, :default => "", :null => false
|
|
||||||
t.column :value_type, :string
|
|
||||||
t.column :value, :text
|
|
||||||
end
|
|
||||||
add_index :configurable_settings, :name
|
|
||||||
|
|
||||||
create_table :test_groups, :force => true do |t|
|
|
||||||
t.column :display_name, :string, :limit => 80
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table :test_users, :force => true do |t|
|
|
||||||
t.column :login, :string, :limit => 20
|
|
||||||
t.column :name, :string, :limit => 80
|
|
||||||
t.column :email, :string
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
ActiveRecord::Migration.verbose = true
|
|
|
@ -1,30 +0,0 @@
|
||||||
ENV["RAILS_ENV"] = "test"
|
|
||||||
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
|
||||||
|
|
||||||
require 'test/unit'
|
|
||||||
require 'active_record/fixtures'
|
|
||||||
|
|
||||||
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
|
||||||
|
|
||||||
load(File.dirname(__FILE__) + '/schema.rb')
|
|
||||||
|
|
||||||
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + '/fixtures/'
|
|
||||||
$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
|
|
||||||
|
|
||||||
class Test::Unit::TestCase #:nodoc:
|
|
||||||
def create_fixtures(*table_names)
|
|
||||||
if block_given?
|
|
||||||
Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
|
|
||||||
else
|
|
||||||
Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Turn off transactional fixtures if you're working with MyISAM tables in MySQL
|
|
||||||
self.use_transactional_fixtures = true
|
|
||||||
|
|
||||||
# Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
|
|
||||||
self.use_instantiated_fixtures = false
|
|
||||||
|
|
||||||
# Add more helper methods to be used by all tests here...
|
|
||||||
end
|
|
Loading…
Reference in a new issue