Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
bemurphy committed Apr 22, 2010
0 parents commit dea706f
Show file tree
Hide file tree
Showing 21 changed files with 539 additions and 0 deletions.
20 changes: 20 additions & 0 deletions MIT-LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2010 [name of plugin creator]

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.
13 changes: 13 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
ActsAsOptionable
================

Introduction goes here.


Example
=======

Example goes here.


Copyright (c) 2010 [name of plugin creator], released under the MIT license
23 changes: 23 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

desc 'Default: run unit tests.'
task :default => :test

desc 'Test the acts_as_optionable plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end

desc 'Generate documentation for the acts_as_optionable plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'ActsAsOptionable'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end
8 changes: 8 additions & 0 deletions generators/option/option_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class OptionGenerator < Rails::Generator::Base
def manifest
record do |m|
m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => 'create_options'
m.template 'model.rb', 'app/models/option.rb'
end
end
end
14 changes: 14 additions & 0 deletions generators/option/templates/migration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreateOptions < ActiveRecord::Migration
def self.up
create_table :options do |t|
t.string :name
t.string :value
t.references :optionable, :polymorphic => true
t.timestamps
end
end

def self.down
drop_table :options
end
end
59 changes: 59 additions & 0 deletions generators/option/templates/model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
class Option < ActiveRecord::Base
include ActiveRecord::Acts::Optionable
extend ActiveSupport::Memoizable

belongs_to :optionable, :polymorphic => true

default_scope :order => 'created_at ASC'

validates_uniqueness_of :name, :scope => [:optionable_id, :optionable_type]
validates_presence_of [:optionable_type, :optionable_id]

attr_accessor :default

def value
val = read_attribute(:value)
val ? YAML.load(val) : default
end
memoize :value

def value_or_default
value || default
end
memoize :value_or_default

def value=(val)
unless value_class_ok?(val)
raise ArgumentError, "Only store booleans, numbers, and strings, please"
end

write_attribute(:value, val.to_yaml)
end

def display_name
name.humanize.titleize
end

# def default_value
# @config['default']
# end
#
# def evaluated_value
# value && !value.empty? ? value : default_value
# end
#
# def color?
# @config['type'] == :color
# end
#
# def config=(h)
# @config = h
# write_attribute(:name, h['name'])
# end

protected

def value_class_ok?(val)
val.is_a?(TrueClass) || val.is_a?(FalseClass) || val.kind_of?(Numeric) || val.is_a?(String)
end
end
1 change: 1 addition & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require File.dirname(__FILE__) + "/rails/init"
1 change: 1 addition & 0 deletions install.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Install hook code here
3 changes: 3 additions & 0 deletions lib/acts-as-optionable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require "acts_as_optionable/acts_as_optionable"
require "acts_as_optionable/option_methods"
require "acts_as_optionable/specify_option"
1 change: 1 addition & 0 deletions lib/acts_as_optionable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ActsAsOptionable
72 changes: 72 additions & 0 deletions lib/acts_as_optionable/acts_as_optionable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module ActiveRecord
module Acts
module Optionable
def self.included(base)
base.extend ClassMethods
end

module ClassMethods
def acts_as_optionable
has_many :options, :as => :optionable, :dependent => :destroy
include IntanceMethods
extend ActiveRecord::Acts::Optionable::SpecifyOption::ClassMethods
include ActiveRecord::Acts::Optionable::SpecifyOption::InstanceMethods
end
end

module IntanceMethods
def set_option(name, value)
option = get_stored_option(name) || options.build(:name => name.to_s)
return if new_option_matches_current?(option)
option.value = value
ret = option.save!
options(:reload)
ret
end

def get_option(name)
get_stored_option(name) ||
get_default_option(name)
end

def get_default_option(name)
instance_specified_option(name) || self.class.get_specified_option(name)
end

def get_default_options
self.class.optionable_specified_options.merge(instance_specified_options || {})
end

def delete_option(name)
if option = options(:reload).find_by_name(name.to_s)
option = option.destroy
options(:reload)
option
end
end

def options_and_defaults
options_as_hash = options.inject({}) do |memo, option|
memo[option.name.to_s] = option
memo
end
get_default_options.merge(options_as_hash)
end

def specified_options
raise "TODO"
end

protected

def get_stored_option(name)
options.detect { |option| option.name.to_s == name.to_s }
end

def new_option_matches_current?(option)
(!option.new_record? && option.value == value) || (get_default_option(name).value == value rescue nil)
end
end
end
end
end
17 changes: 17 additions & 0 deletions lib/acts_as_optionable/option_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module ActiveRecord
module Acts
module Optionable
module OptionMethods
def self.included(option_model)
option_model.extend Finders
end

module Finders
def find_options_for_optionable(optionable_str, optionable_id)
all(:conditions => { :optionable_type => optionable_str, :optionable_id => optionable_id }, :order => "created_at DESC")
end
end
end
end
end
end
13 changes: 13 additions & 0 deletions lib/acts_as_optionable/options_template.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# module ActiveRecord
# module Acts
# module Optionable
# module SpecifyOption
# class OptionsTemplate
# def initialize(template_hash = {})
#
# end
# end
# end
# end
# end
# end
40 changes: 40 additions & 0 deletions lib/acts_as_optionable/specify_option.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module ActiveRecord
module Acts
module Optionable
module SpecifyOption
module ClassMethods
def specify_option(option_name, opts = {})
optionable_specified_options[option_name.to_s] = Option.new(:name => option_name.to_s, :default => opts[:default])
end

def optionable_specified_options
@optionable_specified_options ||= {}
end

def get_specified_option(option_name)
optionable_specified_options[option_name.to_s]
end

end

module InstanceMethods
attr_reader :instance_specified_options

def instance_specified_option(option_name)
instance_specified_options[option_name.to_s] if instance_specified_options
end

def instance_specified_options=(opts)
opts.symbolize_keys!
@instance_specified_options = {}
opts.each do |option_name, attributes|
attributes.symbolize_keys!
@instance_specified_options[option_name.to_s] = Option.new(:name => option_name.to_s,
:default => attributes[:default])
end
end
end
end
end
end
end
5 changes: 5 additions & 0 deletions rails/init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require "acts-as-optionable"

ActiveRecord::Base.send(:include, ActiveRecord::Acts::Optionable)

RAILS_DEFAULT_LOGGER.info "** acts_as_optionable: initialized properly."
Loading

0 comments on commit dea706f

Please sign in to comment.