forked from squeejee/acts_as_redeemable
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Wynn Netherland
committed
Jul 10, 2008
0 parents
commit f5d79f7
Showing
16 changed files
with
324 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2007 [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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
= ActsAsRedeemable | ||
|
||
|
||
Adds redemption capability to a model for items like coupons, invitation codes, etc. | ||
|
||
Each redeemable gets a unique code upon creation that can be sent in an email or printed as a coupon code. | ||
|
||
|
||
== Usage | ||
|
||
=== Optionally generate the model | ||
|
||
script/generate redeemable Coupon | ||
rake db:migrate | ||
|
||
|
||
=== Make your ActiveRecord model act as redeemable. | ||
|
||
class Coupon < ActiveRecord::Base | ||
acts_as_redeemable :valid_for => 30.days, :code_length => 8 # optional expiration, code length | ||
end | ||
|
||
=== Create a new instance | ||
|
||
c = Coupon.new | ||
c.user_id = 1 # The user who created the coupon | ||
c.save | ||
c.code | ||
# "4D9110A3" | ||
c.created_at | ||
# Fri Feb 15 14:56:37 -0600 2008 | ||
c.expires_on | ||
# Fri Mar 16 14:56:37 -0600 2008 | ||
|
||
|
||
|
||
|
||
Copyright (c) 2008 Squeejee, released under the MIT license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
h2. ActsAsRedeemable | ||
|
||
Adds redemption capability to a model for items like coupons, invitation codes, etc. Each redeemable gets a unique code upon creation that can be sent in an email or printed as a coupon code. | ||
|
||
|
||
h2. Usage | ||
|
||
h3. Optionally generate the model | ||
|
||
script/generate redeemable Coupon | ||
rake db:migrate | ||
|
||
|
||
h3. Make your ActiveRecord model act as redeemable. | ||
|
||
class Coupon < ActiveRecord::Base | ||
acts_as_redeemable :valid_for => 30.days, :code_length => 8 # optional expiration, code length | ||
end | ||
|
||
h3. Create a new instance | ||
|
||
c = Coupon.new | ||
c.user_id = 1 # The user who created the coupon | ||
c.save | ||
c.code | ||
# "4D9110A3" | ||
c.created_at | ||
# Fri Feb 15 14:56:37 -0600 2008 | ||
c.expires_on | ||
# Fri Mar 16 14:56:37 -0600 2008</code></pre> | ||
|
||
Copyright (c) 2008 Squeejee, released under the MIT license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'rake' | ||
require 'rake/testtask' | ||
require 'rake/rdoctask' | ||
|
||
desc 'Default: run unit tests.' | ||
task :default => :test | ||
|
||
desc 'Test the acts_as_redeemable 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_redeemable plugin.' | ||
Rake::RDocTask.new(:rdoc) do |rdoc| | ||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = 'ActsAsRedeemable' | ||
rdoc.options << '--line-numbers' << '--inline-source' | ||
rdoc.rdoc_files.include('README') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require 'acts_as_redeemable' | ||
ActiveRecord::Base.send(:include, Squeejee::Acts::Redeemable) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Install hook code here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
require 'md5' | ||
module Squeejee #:nodoc: | ||
module Acts #:nodoc: | ||
module Redeemable #:nodoc: | ||
def self.included(base) | ||
base.extend(ClassMethods) | ||
end | ||
# This act provides the capabilities for redeeming and expiring models. Useful for things like | ||
# coupons, invitations, and special offers. | ||
# | ||
# Coupon example: | ||
# | ||
# class Coupon < ActiveRecord::Base | ||
# acts_as_redeemable :valid_for => 30.days, :code_length => 8 # optional expiration, code length | ||
# end | ||
# | ||
# | ||
# c = Coupon.new | ||
# c.user_id = 1 # The user who created the coupon | ||
# c.save | ||
# c.code | ||
# | ||
# # "4D9110A3" | ||
module ClassMethods | ||
# Configuration options are: | ||
# | ||
# * +valid_for+ - specifies the duration until redeemable expire. Default is no expiration | ||
# * +code_length+ - set the length of the generated unique code. Default is six alphanumeric characters | ||
# * example: <tt>acts_as_redeemable :valid_for => 30.days, :code_length => 8</tt> | ||
def acts_as_redeemable(options = {}) | ||
unless redeemable? # don't let AR call this twice | ||
cattr_accessor :valid_for | ||
cattr_accessor :code_length | ||
before_create :setup_new | ||
self.valid_for = options[:valid_for] unless options[:valid_for].nil? | ||
self.code_length = (options[:code_length].nil? ? 6 : options[:code_length]) | ||
end | ||
include InstanceMethods | ||
|
||
# Generates an alphanumeric code using an MD5 hash | ||
# * +code_length+ - number of characters to return | ||
def generate_code(code_length=6) | ||
chars = ("a".."z").to_a + ("1".."9").to_a | ||
new_code = Array.new(code_length, '').collect{chars[rand(chars.size)]}.join | ||
Digest::MD5.hexdigest(new_code)[0..(code_length-1)].upcase | ||
end | ||
|
||
# Generates unique code based on +generate_code+ method | ||
def generate_unique_code | ||
begin | ||
new_code = generate_code(self.code_length) | ||
end until !active_code?(new_code) | ||
new_code | ||
end | ||
|
||
# Checks the database to ensure the specified code is not taken | ||
def active_code?(code) | ||
find :first, :conditions => {:code => code} | ||
end | ||
|
||
end | ||
|
||
def redeemable? #:nodoc: | ||
self.included_modules.include?(InstanceMethods) | ||
end | ||
end | ||
|
||
module InstanceMethods | ||
|
||
# Marks the redeemable redeemed by the given user id | ||
# * +redeemed_by_id+ - id of redeeming user | ||
def redeem!(redeemed_by_id) | ||
unless self.redeemed? or self.expired? | ||
self.update_attributes({:redeemed_by_id => redeemed_by_id, :recipient_id => redeemed_by_id, :redeemed_at => Time.now}) | ||
self.after_redeem | ||
end | ||
end | ||
|
||
# Returns whether or not the redeemable has been redeemed | ||
def redeemed? | ||
self.redeemed_at? | ||
end | ||
|
||
# Returns whether or not the redeemable has expired | ||
def expired? | ||
self.expires_on? and self.expires_on < Time.now | ||
end | ||
|
||
def setup_new #:nodoc: | ||
self.code = self.class.generate_unique_code | ||
unless self.class.valid_for.nil? or self.expires_on? | ||
self.expires_on = self.created_at + self.class.valid_for | ||
end | ||
end | ||
|
||
# Callback for business logic to implement after redemption | ||
def after_redeem() end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
class RedeemableGenerator < Rails::Generator::NamedBase #:nodoc: | ||
def manifest | ||
record do |m| | ||
m.class_collisions class_name | ||
|
||
m.template "app/models/model_template.rb", "app/models/#{file_name}.rb" | ||
|
||
unless options[:skip_migration] | ||
m.directory 'db/migrate' | ||
m.migration_template 'db/migration.rb', 'db/migrate', :assigns => { | ||
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" | ||
}, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" | ||
end | ||
|
||
m.template "test/fixtures/model.yml", "test/fixtures/#{table_name}.yml" | ||
m.template "test/unit/model_test.rb", "test/unit/#{file_name}.rb" | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
script/generate redeemable (ModelName) | ||
|
||
Example: | ||
|
||
script/generate redeemable Coupon | ||
|
||
This will create a Coupon model |
7 changes: 7 additions & 0 deletions
7
lib/generators/redeemable/templates/app/models/model_template.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class <%= class_name %> < ActiveRecord::Base | ||
acts_as_redeemable | ||
belongs_to :user | ||
belongs_to :redeemed_by, :class_name => "User", :foreign_key => "redeemed_by_id" | ||
validates_presence_of :user_id | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
class <%= migration_name %> < ActiveRecord::Migration | ||
def self.up | ||
create_table :<%= table_name %> do |t| | ||
|
||
t.column :user_id, :integer | ||
t.column :code, :string | ||
|
||
t.column :created_at, :datetime | ||
t.column :redeemed_at, :datetime | ||
t.column :redeemed_by_id, :integer | ||
|
||
t.column :expires_on => :datetime | ||
end | ||
end | ||
|
||
def self.down | ||
drop_table :<%= table_name %> | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html | ||
one: | ||
id: 1 | ||
two: | ||
id: 2 |
10 changes: 10 additions & 0 deletions
10
lib/generators/redeemable/templates/test/unit/model_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
require File.dirname(__FILE__) + '/../test_helper' | ||
|
||
class <%= class_name %>Test < Test::Unit::TestCase | ||
fixtures :<%= file_name %> | ||
|
||
# Replace this with your real tests. | ||
def test_truth | ||
assert true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
require 'test/unit' | ||
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb')) | ||
require File.dirname(__FILE__) + '/../lib/acts_as_redeemable' | ||
load(File.dirname(__FILE__) + "/schema.rb") | ||
|
||
class FreeTodayCoupon < ActiveRecord::Base | ||
acts_as_redeemable | ||
|
||
end | ||
|
||
class ActsAsRedeemableTest < Test::Unit::TestCase | ||
# Replace this with your real tests. | ||
def test_should_generate_six_digit_code | ||
assert_equal FreeTodayCoupon.generate_unique_code.length, 6 | ||
end | ||
|
||
def test_should_mark_redeemed | ||
f = FreeTodayCoupon.create(:user_id => 1) | ||
f.redeem!(2) | ||
assert f.redeemed? | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
ActiveRecord::Schema.define(:version => 1) do | ||
|
||
create_table :free_today_coupons, :force => true do |t| | ||
|
||
t.column :user_id, :integer | ||
t.column :code, :string | ||
|
||
t.column :created_at, :datetime | ||
t.column :redeemed_at, :datetime | ||
t.column :redeemed_by_id, :integer | ||
|
||
end | ||
|
||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require 'acts_as_redeemable' | ||
ActiveRecord::Base.send(:include, Squeejee::Acts::Redeemable) |