Initial import
This commit is contained in:
9
vendor/gems/dr_nic_magic_models-0.9.2/CHANGELOG
vendored
Normal file
9
vendor/gems/dr_nic_magic_models-0.9.2/CHANGELOG
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
* 0.2.5 * - Initial public release
|
||||
- ActiveRecords can now be auto-created in memory when first referenced
|
||||
from their table name, without an explicit class definition.
|
||||
- ActiveRecords will automatically include validates_presence_of on
|
||||
each field with :null => false
|
||||
- ActiveRecords will automatically generate simple has_many, has_one,
|
||||
belongs_to assocations based upon assumed foreign keys. E.g.
|
||||
foreign key to products table is assumed to be product_id.
|
||||
|
||||
28
vendor/gems/dr_nic_magic_models-0.9.2/History.txt
vendored
Normal file
28
vendor/gems/dr_nic_magic_models-0.9.2/History.txt
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
*** 0.9.2 / 2007-4-30
|
||||
|
||||
+ 1 major buxfix:
|
||||
+ #generate_validations now works if you haven't already created a connection to the database; previously
|
||||
validations wouldn't get created until you had already established the connection; now it does it for
|
||||
you if its not already established
|
||||
+ Associations can be generated via the assignment methods, e.g. @membership.group= will generate the "belongs_to :group" association now. This allows the website tutorial to work correctly! Yay. That is, you can now do: Membership.create(:person => person, :group => group)
|
||||
+ has_many's should work now
|
||||
|
||||
*** 0.9.1 / 2007-4-11
|
||||
|
||||
+ 1 minor enhancement:
|
||||
+ ActiveRecord::Base includes all the magic model functionality via the MagicModel module
|
||||
+ Existing ARs can get magic validation via #generate_validations call
|
||||
+ Website tutorial works :D
|
||||
|
||||
*** 0.9.0 / 2007-4-9
|
||||
|
||||
+ 1 major enhancement:
|
||||
+ Support for dynamic loading of classes again
|
||||
+ 2 new DB supported:
|
||||
+ Tests run on sqlite (no fk support)
|
||||
+ Tests run on postgresql (fk support)
|
||||
+ Including FK bug fix
|
||||
+ Many fixes that I've lost track of
|
||||
+ History.txt to keep track of changes like these
|
||||
+ Using Hoe for Rakefile
|
||||
+ Use modules to specify common table prefixes
|
||||
56
vendor/gems/dr_nic_magic_models-0.9.2/Manifest.txt
vendored
Normal file
56
vendor/gems/dr_nic_magic_models-0.9.2/Manifest.txt
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
CHANGELOG
|
||||
History.txt
|
||||
Manifest.txt
|
||||
README
|
||||
Rakefile
|
||||
install.rb
|
||||
lib/base.rb
|
||||
lib/connection_adapters/abstract/schema_statements.rb
|
||||
lib/connection_adapters/abstract_adapter.rb
|
||||
lib/connection_adapters/mysql_adapter.rb
|
||||
lib/connection_adapters/postgresql_adapter.rb
|
||||
lib/dr_nic_magic_models.rb
|
||||
lib/dr_nic_magic_models/inflector.rb
|
||||
lib/dr_nic_magic_models/magic_model.rb
|
||||
lib/dr_nic_magic_models/schema.rb
|
||||
lib/dr_nic_magic_models/validations.rb
|
||||
lib/dr_nic_magic_models/version.rb
|
||||
lib/module.rb
|
||||
lib/rails.rb
|
||||
scripts/txt2html
|
||||
scripts/txt2js
|
||||
test.db
|
||||
test/abstract_unit.rb
|
||||
test/connections/native_mysql/connection.rb
|
||||
test/connections/native_postgresql/connection.rb
|
||||
test/connections/native_sqlite/connection.rb
|
||||
test/dummy_test.rb
|
||||
test/env_test.rb
|
||||
test/fixtures/.DS_Store
|
||||
test/fixtures/adjectives.yml
|
||||
test/fixtures/adjectives_fun_users.yml
|
||||
test/fixtures/db_definitions/mysql.drop.sql
|
||||
test/fixtures/db_definitions/mysql.sql
|
||||
test/fixtures/db_definitions/postgresql.sql
|
||||
test/fixtures/db_definitions/sqlite.sql
|
||||
test/fixtures/fun_users.yml
|
||||
test/fixtures/group_memberships.yml
|
||||
test/fixtures/group_tag.yml
|
||||
test/fixtures/groups.yml
|
||||
test/foreign_keys_test.rb
|
||||
test/fun_user_plus.rb
|
||||
test/invisible_model_access_test.rb
|
||||
test/invisible_model_assoc_test.rb
|
||||
test/invisible_model_classes_test.rb
|
||||
test/magic_module_test.rb
|
||||
test/test_existing_model.rb
|
||||
website/index.html
|
||||
website/index.txt
|
||||
website/javascripts/rounded_corners_lite.inc.js
|
||||
website/stylesheets/screen.css
|
||||
website/template.js
|
||||
website/template.rhtml
|
||||
website/version-raw.js
|
||||
website/version-raw.txt
|
||||
website/version.js
|
||||
website/version.txt
|
||||
294
vendor/gems/dr_nic_magic_models-0.9.2/README
vendored
Normal file
294
vendor/gems/dr_nic_magic_models-0.9.2/README
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
See http://magicmodels.rubyforge.org/dr_nic_magic_models for pretty README
|
||||
|
||||
Ugly README (from website/index.txt in Textile format):
|
||||
h1. Dr Nic's Magic Models
|
||||
|
||||
If you've used Ruby on Rails you'll have written at least one model class like this:
|
||||
|
||||
<pre syntax='ruby'>
|
||||
class Person < ActiveRecord::Base
|
||||
has_many :memberships
|
||||
has_many :groups, :through => :memberships
|
||||
belongs_to :family
|
||||
validates_presence_of :firstname, :lastname, :email
|
||||
end
|
||||
</pre>
|
||||
|
||||
A few minutes later you'll have wondered to yourself,
|
||||
|
||||
<blockquote>
|
||||
Why do I have write my own <code>has_many</code>, <code>belongs_to</code>, and <code>validates_presence_of</code>
|
||||
commands if all the data is in the database schema?
|
||||
</blockquote>
|
||||
|
||||
Now, for the very first time, your classes can look like this:
|
||||
|
||||
<pre syntax='ruby'>
|
||||
class Person < ActiveRecord::Base
|
||||
end
|
||||
</pre>
|
||||
|
||||
or, if you are lazy...
|
||||
|
||||
<pre syntax='ruby'>
|
||||
class Person < ActiveRecord::Base; end
|
||||
</pre>
|
||||
|
||||
or, if you read right to the end of this page, this...
|
||||
|
||||
<pre syntax='ruby'>
|
||||
# Go fish.
|
||||
</pre>
|
||||
|
||||
Magic and mystery abound. All for you. Impress your friends, amaze your mother.
|
||||
|
||||
NOTE: The gratuitous use of *Dr Nic's* in the name should only enhance the mystical magikery,
|
||||
for magic needs a magician; and I love magic. I always wanted to create my own magic trick.
|
||||
So I shall be the magician for the sake of magic itself. I look a bit like Harry Potter too,
|
||||
if Harry were 32 and better dressed.
|
||||
|
||||
h2. Installation
|
||||
|
||||
To install the Dr Nic's Magic Models gem you can run the following command to
|
||||
fetch the gem remotely from RubyForge:
|
||||
<pre>
|
||||
gem install dr_nic_magic_models
|
||||
</pre>
|
||||
|
||||
or "download the gem manually":http://rubyforge.org/projects/magicmodels and
|
||||
run the above command in the download directory.
|
||||
|
||||
Now you need to <code>require</code> the gem into your Ruby/Rails app. Insert the following
|
||||
line into your script (use <code>config/environment.rb</code> for your Rails apps):
|
||||
|
||||
<pre>
|
||||
require 'dr_nic_magic_models'
|
||||
</pre>
|
||||
|
||||
Your application is now blessed with magical mystery.
|
||||
|
||||
h2. David Copperfield eat your Ruby-crusted heart out
|
||||
|
||||
Let's demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app (example uses sqlite3, but use your favourite databas):
|
||||
|
||||
<pre syntax="ruby">
|
||||
rails magic_show -d sqlite3
|
||||
cd magic_show
|
||||
ruby script/generate model Person
|
||||
ruby script/generate model Group
|
||||
ruby script/generate model Membership
|
||||
</pre>
|
||||
|
||||
Update the migration <code>001_create_people.rb</code> with:
|
||||
<pre syntax="ruby">
|
||||
class CreatePeople < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :people do |t|
|
||||
t.column :firstname, :string, :null => false
|
||||
t.column :lastname, :string, :null => false
|
||||
t.column :email, :string, :null => false
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :people
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
Similarly, update the <code>def self.up</code> method of <code>002_create_groups.rb</code>
|
||||
with:
|
||||
<pre syntax="ruby">
|
||||
create_table :groups do |t|
|
||||
t.column :name, :string, :null => false
|
||||
t.column :description, :string
|
||||
end
|
||||
</pre>
|
||||
|
||||
and <code>003_create_memberships.rb</code> with:
|
||||
<pre syntax="ruby">
|
||||
create_table :memberships do |t|
|
||||
t.column :person_id, :integer, :null => false
|
||||
t.column :group_id, :integer, :null => false
|
||||
end
|
||||
</pre>
|
||||
|
||||
And run your migrations to create the three tables:
|
||||
<pre>
|
||||
rake db:migrate
|
||||
</pre>
|
||||
|
||||
h3. And now for some "woofle dust":http://en.wikipedia.org/wiki/List_of_conjuring_terms ...
|
||||
|
||||
At the end of <code>config/environment.rb</code> add the following line:
|
||||
|
||||
<pre>
|
||||
require 'dr_nic_magic_models'
|
||||
</pre>
|
||||
|
||||
Now, let's do a magic trick. First, let's check our model classes (<code>app/models/person.rb</code> etc):
|
||||
|
||||
<pre syntax="ruby">
|
||||
class Person < ActiveRecord::Base
|
||||
end
|
||||
class Group < ActiveRecord::Base
|
||||
end
|
||||
class Membership < ActiveRecord::Base
|
||||
end
|
||||
</pre>
|
||||
|
||||
Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.
|
||||
|
||||
UPDATE: To turn on magic validations, you now need to invoke <code>generate_validations</code> on defined classes. So, update your model classes:
|
||||
|
||||
<pre syntax="ruby">
|
||||
class Person < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
class Group < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
class Membership < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
</pre>
|
||||
|
||||
For this trick, we'll need an ordinary console session. Any old one lying around the house will do.
|
||||
|
||||
<pre>
|
||||
ruby script/console
|
||||
</pre>
|
||||
|
||||
Now a normal model class is valid until you explicitly add <code>validates_xxx</code> commands.
|
||||
With Dr Nic's Magic Models:
|
||||
|
||||
<pre syntax="ruby">
|
||||
person = Person.new
|
||||
=> #<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>
|
||||
person.valid?
|
||||
=> false
|
||||
person.errors
|
||||
=> #<ActiveRecord::Errors:0x3537b38 @errors={
|
||||
"firstname"=>["can't be blank", "is too long (maximum is 255 characters)"],
|
||||
"lastname"=>["can't be blank", "is too long (maximum is 255 characters)"],
|
||||
"email"=>["can't be blank", "is too long (maximum is 255 characters)"]},
|
||||
@base=#<Person:0x3538bf0 @errors=#<ActiveRecord::Errors:0x3537b38 ...>, @new_record=true,
|
||||
@attributes={"lastname"=>nil, "firstname"=>nil, "email"=>nil}>>
|
||||
</pre>
|
||||
|
||||
*Kapoow!* Instant validation! (NOTE: not as instant as it used to be - remember - you need to call <code>generate_validations</code> on each class as required)
|
||||
|
||||
Because you specified the three columns as <code>:null => false</code>,
|
||||
your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
|
||||
for each non-null field, plus several other validations (since version 0.8.0).
|
||||
|
||||
Ok, we're just warming up.
|
||||
|
||||
Your models normally require association commands (<code>has_many</code>, <code>belongs_to</code>, etc, as
|
||||
demonstrated above) to have the brilliantly simple support that Rails/ActiveRecords are known for.
|
||||
|
||||
Let's just watch what Dr Nic's Magic Models can do without any effort at all...
|
||||
|
||||
<pre syntax="ruby">
|
||||
person = Person.create(:firstname => "Nic", :lastname => "Williams", :email => "drnicwilliams@gmail.com")
|
||||
group = Group.create(:name => "Magic Models Forum", :description => "http://groups.google.com/magicmodels")
|
||||
membership = Membership.create(:person => person, :group => group)
|
||||
person.memberships.length
|
||||
=> 1
|
||||
membership.person
|
||||
=> <Person:0x38898e8 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
||||
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
|
||||
group.memberships
|
||||
=> [<Membership:0x3c8cd70 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
|
||||
</pre>
|
||||
|
||||
|
||||
The final association trick is a ripper. Automatic generation of <code>has_many :through</code> associations...
|
||||
|
||||
<pre syntax="ruby">
|
||||
>> person.groups
|
||||
=> [<Group:0x39047e0 @attributes={"name"=>"Magic Models Forum", "id"=>"1", "description"=>nil}>]
|
||||
>> group.people
|
||||
=> [<Person:0x3c33580 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
||||
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>]
|
||||
</pre>
|
||||
|
||||
h3. Drum roll...
|
||||
|
||||
Ladies and gentlemen. For my final feat of magical mastery, I'll ask you to do
|
||||
something you've never done before. This illusion is akin to the "floating lady":http://www.toytent.com/Posters/985.html
|
||||
illusion that has been passed down through generations of magicians.
|
||||
|
||||
Exit your console session.
|
||||
|
||||
DELETE your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
|
||||
<code>app/models</code> folder. (You can always get them back via the model generator... be fearless!)
|
||||
|
||||
<pre>rm app/models/*.rb</pre>
|
||||
|
||||
Re-launch your console.
|
||||
|
||||
*drums are still rolling...*
|
||||
|
||||
Be prepared to applaud loudly...
|
||||
|
||||
<pre syntax="ruby">
|
||||
>> Person
|
||||
=> Person
|
||||
</pre>
|
||||
|
||||
You applaud loudly, but watch for more...
|
||||
|
||||
<pre syntax="ruby">
|
||||
>> Person.new.valid?
|
||||
=> false
|
||||
>> person = Person.find(1)
|
||||
=> <Person:0x3958930 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
||||
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
|
||||
>> person.valid?
|
||||
=> true
|
||||
>> person.memberships
|
||||
=> [<Membership:0x393a000 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
|
||||
>> person.groups
|
||||
=> [<Group:0x390df60 @attributes={"name"=>"Magic Models Forum", "id"=>"1", "description"=>nil}>]
|
||||
</pre>
|
||||
|
||||
h3. Tada!
|
||||
|
||||
The end.
|
||||
|
||||
h3. Use modules to scope your magic
|
||||
|
||||
Only want to pick up tables starting with <code>blog_</code>?
|
||||
|
||||
<pre syntax="ruby">module Blog
|
||||
magic_module :table_name_prefix => 'blog_'
|
||||
end
|
||||
|
||||
Blog::Post.table_name # => 'blog_posts'
|
||||
</pre>
|
||||
|
||||
h2. Dr Nic's Blog
|
||||
|
||||
"http://www.drnicwilliams.com":http://www.drnicwilliams.com - for future announcements and
|
||||
other stories and things.
|
||||
|
||||
h2. Articles about Magic Models
|
||||
|
||||
* "Announcement":http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/
|
||||
* "BTS - Class creation":http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/
|
||||
|
||||
|
||||
h2. Forum
|
||||
|
||||
"http://groups.google.com/group/magicmodels":http://groups.google.com/group/magicmodels
|
||||
|
||||
h2. Licence
|
||||
|
||||
This code is free to use under the terms of the MIT licence.
|
||||
|
||||
h2. Contact
|
||||
|
||||
Comments are welcome. Send an email to "Dr Nic Williams":mailto:drnicwilliams@gmail.com
|
||||
or via his blog at "http://www.drnicwilliams.com":http://www.drnicwilliams.com
|
||||
|
||||
134
vendor/gems/dr_nic_magic_models-0.9.2/Rakefile
vendored
Normal file
134
vendor/gems/dr_nic_magic_models-0.9.2/Rakefile
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
require 'rubygems'
|
||||
require 'rake'
|
||||
require 'rake/clean'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/packagetask'
|
||||
require 'rake/gempackagetask'
|
||||
require 'rake/contrib/rubyforgepublisher'
|
||||
require 'hoe'
|
||||
require File.join(File.dirname(__FILE__), 'lib', 'dr_nic_magic_models', 'version')
|
||||
|
||||
AUTHOR = "nicwilliams" # can also be an array of Authors
|
||||
EMAIL = "drnicwilliams@gmail.com"
|
||||
DESCRIPTION = "Dr Nic's Magic Models - Invisible validations, assocations and Active Record models themselves!"
|
||||
GEM_NAME = "dr_nic_magic_models" # what ppl will type to install your gem
|
||||
RUBYFORGE_PROJECT = "magicmodels" # The unix name for your project
|
||||
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
||||
|
||||
|
||||
NAME = "magic_multi_connections"
|
||||
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
||||
VERS = ENV['VERSION'] || (DrNicMagicModels::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
||||
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
||||
RDOC_OPTS = ['--quiet', '--title', "dr_nic_magic_models documentation",
|
||||
"--opname", "index.html",
|
||||
"--line-numbers",
|
||||
"--main", "README",
|
||||
"--inline-source"]
|
||||
|
||||
class Hoe
|
||||
def extra_deps
|
||||
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
||||
end
|
||||
end
|
||||
|
||||
# Generate all the Rake tasks
|
||||
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
||||
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
||||
p.author = AUTHOR
|
||||
p.description = DESCRIPTION
|
||||
p.email = EMAIL
|
||||
p.summary = DESCRIPTION
|
||||
p.url = HOMEPATH
|
||||
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
||||
p.test_globs = ["test/**/test_*.rb"]
|
||||
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
||||
|
||||
# == Optional
|
||||
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
||||
|
||||
#p.extra_deps - An array of rubygem dependencies.
|
||||
#p.spec_extras - A hash of extra values to set in the gemspec.
|
||||
end
|
||||
|
||||
# Run the unit tests
|
||||
|
||||
for adapter in %w( sqlite mysql postgresql ) # UNTESTED - postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oracle sybase openbase )
|
||||
Rake::TestTask.new("test_#{adapter}") { |t|
|
||||
t.libs << "test" << "test/connections/native_#{adapter}"
|
||||
t.pattern = "test/*_test{,_#{adapter}}.rb"
|
||||
t.verbose = true
|
||||
}
|
||||
end
|
||||
|
||||
SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions))
|
||||
|
||||
desc 'Build the MySQL test databases'
|
||||
task :build_mysql_databases do
|
||||
puts File.join(SCHEMA_PATH, 'mysql.sql')
|
||||
%x( mysqladmin -u root create "#{GEM_NAME}_unittest" )
|
||||
cmd = "mysql -u root #{GEM_NAME}_unittest < \"#{File.join(SCHEMA_PATH, 'mysql.sql')}\""
|
||||
puts "#{cmd}\n"
|
||||
%x( #{cmd} )
|
||||
end
|
||||
|
||||
desc 'Drop the MySQL test databases'
|
||||
task :drop_mysql_databases do
|
||||
%x( mysqladmin -u root -f drop "#{GEM_NAME}_unittest" )
|
||||
end
|
||||
|
||||
desc 'Rebuild the MySQL test databases'
|
||||
task :rebuild_mysql_databases => [:drop_mysql_databases, :build_mysql_databases]
|
||||
|
||||
desc 'Build the sqlite test databases'
|
||||
task :build_sqlite_databases do
|
||||
# puts File.join(SCHEMA_PATH, 'sqlite.sql')
|
||||
# %x( sqlite3 test.db < test/fixtures/db_definitions/sqlite.sql )
|
||||
file = File.join(SCHEMA_PATH, 'sqlite.sql')
|
||||
cmd = "sqlite3 test.db < #{file}"
|
||||
puts cmd
|
||||
%x( #{cmd} )
|
||||
end
|
||||
|
||||
desc 'Drop the sqlite test databases'
|
||||
task :drop_sqlite_databases do
|
||||
%x( rm -f test.db )
|
||||
end
|
||||
|
||||
desc 'Rebuild the sqlite test databases'
|
||||
task :rebuild_sqlite_databases => [:drop_sqlite_databases, :build_sqlite_databases]
|
||||
|
||||
desc 'Build the PostgreSQL test databases'
|
||||
task :build_postgresql_databases do
|
||||
%x( createdb "#{GEM_NAME}_unittest" )
|
||||
%x( psql "#{GEM_NAME}_unittest" -f "#{File.join(SCHEMA_PATH, 'postgresql.sql')}" )
|
||||
end
|
||||
|
||||
desc 'Drop the PostgreSQL test databases'
|
||||
task :drop_postgresql_databases do
|
||||
%x( dropdb "#{GEM_NAME}_unittest" )
|
||||
end
|
||||
|
||||
desc 'Rebuild the PostgreSQL test databases'
|
||||
task :rebuild_postgresql_databases => [:drop_postgresql_databases, :build_postgresql_databases]
|
||||
|
||||
|
||||
desc 'Generate website files'
|
||||
task :website_generate do
|
||||
sh %{ ruby scripts/txt2html website/index.txt > website/index.html }
|
||||
sh %{ ruby scripts/txt2js website/version.txt > website/version.js }
|
||||
sh %{ ruby scripts/txt2js website/version-raw.txt > website/version-raw.js }
|
||||
end
|
||||
|
||||
desc 'Upload website files to rubyforge'
|
||||
task :website_upload do
|
||||
config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
|
||||
host = "#{config["username"]}@rubyforge.org"
|
||||
remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
||||
local_dir = 'website'
|
||||
sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}}
|
||||
end
|
||||
|
||||
desc 'Generate and upload website files'
|
||||
task :website => [:website_generate, :website_upload]
|
||||
3
vendor/gems/dr_nic_magic_models-0.9.2/init.rb
vendored
Normal file
3
vendor/gems/dr_nic_magic_models-0.9.2/init.rb
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
require File.join(File.dirname(__FILE__), 'lib', 'dr_nic_magic_models')
|
||||
|
||||
30
vendor/gems/dr_nic_magic_models-0.9.2/install.rb
vendored
Normal file
30
vendor/gems/dr_nic_magic_models-0.9.2/install.rb
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
require 'rbconfig'
|
||||
require 'find'
|
||||
require 'ftools'
|
||||
|
||||
include Config
|
||||
|
||||
# this was adapted from rdoc's install.rb by ways of Log4r
|
||||
|
||||
$sitedir = CONFIG["sitelibdir"]
|
||||
unless $sitedir
|
||||
version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
|
||||
$libdir = File.join(CONFIG["libdir"], "ruby", version)
|
||||
$sitedir = $:.find {|x| x =~ /site_ruby/ }
|
||||
if !$sitedir
|
||||
$sitedir = File.join($libdir, "site_ruby")
|
||||
elsif $sitedir !~ Regexp.quote(version)
|
||||
$sitedir = File.join($sitedir, version)
|
||||
end
|
||||
end
|
||||
|
||||
# the acual gruntwork
|
||||
Dir.chdir("lib")
|
||||
|
||||
Find.find("dr_nic_magic_models", "dr_nic_magic_models.rb") { |f|
|
||||
if f[-3..-1] == ".rb"
|
||||
File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true)
|
||||
else
|
||||
File::makedirs(File.join($sitedir, *f.split(/\//)))
|
||||
end
|
||||
}
|
||||
12
vendor/gems/dr_nic_magic_models-0.9.2/lib/base.rb
vendored
Normal file
12
vendor/gems/dr_nic_magic_models-0.9.2/lib/base.rb
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#TODO: Use :dependent for FK cascade?
|
||||
|
||||
module ActiveRecord
|
||||
class Base
|
||||
class << self
|
||||
public
|
||||
def get_unique_index_columns
|
||||
self.connection.indexes(self.table_name, "#{self.name} Indexes").select { |index| index.unique && index.columns.size == 1 }.map{ |index| index.columns.first }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
0
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/abstract/schema_statements.rb
vendored
Normal file
0
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/abstract/schema_statements.rb
vendored
Normal file
32
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/abstract_adapter.rb
vendored
Normal file
32
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/abstract_adapter.rb
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionAdapters # :nodoc:
|
||||
|
||||
# Generic holder for foreign key constraint meta-data from the database schema.
|
||||
class ForeignKeyConstraint < Struct.new(:name, :table, :foreign_key, :reference_table, :reference_column, :on_update, :on_delete)
|
||||
end
|
||||
|
||||
class AbstractAdapter
|
||||
|
||||
# Does this adapter support the ability to fetch foreign key information?
|
||||
# Backend specific, as the abstract adapter always returns +false+.
|
||||
def supports_fetch_foreign_keys?
|
||||
false
|
||||
end
|
||||
|
||||
def foreign_key_constraints(table, name = nil)
|
||||
raise NotImplementedError, "foreign_key_constraints is not implemented for #{self.class}"
|
||||
end
|
||||
|
||||
def remove_foreign_key_constraint(table_name, constraint_name)
|
||||
raise NotImplementedError, "rename_table is not implemented for #{self.class}"
|
||||
end
|
||||
|
||||
protected
|
||||
def symbolize_foreign_key_constraint_action(constraint_action)
|
||||
return nil if constraint_action.nil?
|
||||
constraint_action.downcase.gsub(/\s/, '_').to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
42
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/mysql_adapter.rb
vendored
Normal file
42
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/mysql_adapter.rb
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# Foreign Key support from http://wiki.rubyonrails.org/rails/pages/Foreign+Key+Schema+Dumper+Plugin
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
class MysqlAdapter < AbstractAdapter
|
||||
def supports_fetch_foreign_keys?
|
||||
true
|
||||
end
|
||||
|
||||
def foreign_key_constraints(table, name = nil)
|
||||
constraints = []
|
||||
execute("SHOW CREATE TABLE #{table}", name).each do |row|
|
||||
row[1].each do |create_line|
|
||||
if create_line.strip =~ /CONSTRAINT `([^`]+)` FOREIGN KEY \(`([^`]+)`\) REFERENCES `([^`]+)` \(`([^`]+)`\)([^,]*)/
|
||||
constraint = ForeignKeyConstraint.new(Regexp.last_match(1), table, Regexp.last_match(2), Regexp.last_match(3), Regexp.last_match(4), nil, nil)
|
||||
|
||||
constraint_params = {}
|
||||
|
||||
unless Regexp.last_match(5).nil?
|
||||
Regexp.last_match(5).strip.split('ON ').each do |param|
|
||||
constraint_params[Regexp.last_match(1).upcase] = Regexp.last_match(2).strip.upcase if param.strip =~ /([^ ]+) (.+)/
|
||||
end
|
||||
end
|
||||
|
||||
constraint.on_update = symbolize_foreign_key_constraint_action(constraint_params['UPDATE']) if constraint_params.include? 'UPDATE'
|
||||
constraint.on_delete = symbolize_foreign_key_constraint_action(constraint_params['DELETE']) if constraint_params.include? 'DELETE'
|
||||
|
||||
constraints << constraint
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
constraints
|
||||
end
|
||||
|
||||
def remove_foreign_key_constraint(table_name, constraint_name)
|
||||
execute "ALTER TABLE #{table_name} DROP FOREIGN KEY #{constraint_name}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
45
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/postgresql_adapter.rb
vendored
Normal file
45
vendor/gems/dr_nic_magic_models-0.9.2/lib/connection_adapters/postgresql_adapter.rb
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Foreign Key support from http://wiki.rubyonrails.org/rails/pages/Foreign+Key+Schema+Dumper+Plugin
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
class PostgreSQLAdapter < AbstractAdapter
|
||||
|
||||
def supports_fetch_foreign_keys?
|
||||
true
|
||||
end
|
||||
|
||||
def foreign_key_constraints(table, name = nil)
|
||||
|
||||
|
||||
sql = "SELECT conname, pg_catalog.pg_get_constraintdef(oid) AS consrc FROM pg_catalog.pg_constraint WHERE contype='f' "
|
||||
sql += "AND conrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname='#{table}')"
|
||||
|
||||
result = query(sql, name)
|
||||
|
||||
keys = []
|
||||
re = /(?i)^FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)(?: ON UPDATE (\w+))?(?: ON DELETE (\w+))?$/
|
||||
result.each do |row|
|
||||
# pg_catalog.pg_get_constraintdef returns a string like this:
|
||||
# FOREIGN KEY (user_id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
if match = re.match(row[1])
|
||||
|
||||
keys << ForeignKeyConstraint.new(row[0],
|
||||
table,
|
||||
match[1],
|
||||
match[2],
|
||||
match[3],
|
||||
symbolize_foreign_key_constraint_action(match[4]),
|
||||
symbolize_foreign_key_constraint_action(match[5]))
|
||||
end
|
||||
end
|
||||
|
||||
keys
|
||||
end
|
||||
|
||||
def remove_foreign_key_constraint(table_name, constraint_name)
|
||||
execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{constraint_name}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
34
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models.rb
vendored
Normal file
34
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models.rb
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
$:.unshift(File.dirname(__FILE__)) unless
|
||||
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
||||
|
||||
unless defined?(ActiveRecord)
|
||||
begin
|
||||
require 'active_record'
|
||||
rescue LoadError
|
||||
require 'rubygems'
|
||||
require_gem 'activerecord'
|
||||
end
|
||||
end
|
||||
|
||||
module DrNicMagicModels
|
||||
Logger = RAILS_DEFAULT_LOGGER rescue Logger.new(STDERR)
|
||||
end
|
||||
|
||||
require 'dr_nic_magic_models/magic_model'
|
||||
require 'dr_nic_magic_models/schema'
|
||||
require 'dr_nic_magic_models/validations'
|
||||
require 'dr_nic_magic_models/inflector'
|
||||
require 'base'
|
||||
require 'module'
|
||||
require 'rails' rescue nil
|
||||
require 'connection_adapters/abstract_adapter'
|
||||
require 'connection_adapters/mysql_adapter'
|
||||
require 'connection_adapters/postgresql_adapter'
|
||||
|
||||
# load the schema
|
||||
# TODO - add this to README - DrNicMagicModels::Schema.load_schema(true)
|
||||
|
||||
class ActiveRecord::Base
|
||||
include DrNicMagicModels::MagicModel
|
||||
extend DrNicMagicModels::Validations
|
||||
end
|
||||
14
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/inflector.rb
vendored
Normal file
14
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/inflector.rb
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
module DrNicMagicModels
|
||||
class Inflector
|
||||
def table_names ; DrNicMagicModels::Schema.table_names; end
|
||||
def tables ; DrNicMagicModels::Schema.tables; end
|
||||
def models ; DrNicMagicModels::Schema.model; end
|
||||
|
||||
def class_name(table_name)
|
||||
ActiveRecord::Base.class_name(table_name)
|
||||
end
|
||||
|
||||
def post_class_creation(klass)
|
||||
end
|
||||
end
|
||||
end
|
||||
133
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/magic_model.rb
vendored
Normal file
133
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/magic_model.rb
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
# Mixed into a class that is dynamically created, unless
|
||||
# the class was created by the Schema.load_schema process
|
||||
# which builds the whole class, thus no magicalness is
|
||||
# needed
|
||||
module DrNicMagicModels::MagicModel
|
||||
def self.append_features(base)
|
||||
super
|
||||
base.send(:include, InstanceMethods)
|
||||
class << base
|
||||
# Returns the AssociationReflection object for the named +aggregation+ (use the symbol). Example:
|
||||
# Account.reflect_on_association(:owner) # returns the owner AssociationReflection
|
||||
# Invoice.reflect_on_association(:line_items).macro # returns :has_many
|
||||
def reflect_on_association(association)
|
||||
unless reflections[association]
|
||||
# See if an assocation can be generated
|
||||
self.new.send(association) rescue nil
|
||||
end
|
||||
reflections[association].is_a?(ActiveRecord::Reflection::AssociationReflection) ? reflections[association] : nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
begin
|
||||
super
|
||||
rescue
|
||||
if unknown_method? method
|
||||
result = find_belongs_to method, *args, &block
|
||||
result = find_has_some method, *args, &block if not result
|
||||
result = find_has_some_indirect method, *args, &block if not result
|
||||
return result if result
|
||||
end
|
||||
add_known_unknown method
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
def add_known_unknown(method)
|
||||
@known_unknowns ||= {}
|
||||
@known_unknowns[method] = true
|
||||
end
|
||||
|
||||
def unknown_method?(method)
|
||||
@known_unknowns.nil? or @known_unknowns.include? method
|
||||
end
|
||||
|
||||
def find_belongs_to(method, *args, &block)
|
||||
method_clean = clean_method method
|
||||
fkc =
|
||||
begin
|
||||
self.class.connection.foreign_key_constraints(self.class.table_name, method_clean)
|
||||
rescue NotImplementedError
|
||||
nil
|
||||
end
|
||||
if !fkc.nil? && fkc.length > 0
|
||||
foreign_key = fkc.first.foreign_key
|
||||
options = {:dependent => :destroy,
|
||||
:foreign_key => fkc.first.foreign_key,
|
||||
:class_name => self.class.class_name(fkc.first.reference_table)}
|
||||
else
|
||||
foreign_key = self.class.columns.select {|column| column.name == method_clean.to_s.foreign_key}.first
|
||||
end
|
||||
options ||= {}
|
||||
return add_belongs_to(method, method_clean, options, *args, &block) if foreign_key
|
||||
end
|
||||
|
||||
def add_belongs_to(method, method_clean, options, *args, &block)
|
||||
self.class.send 'belongs_to', method_clean.to_sym, options rescue puts $!
|
||||
self.send(method, *args, &block)
|
||||
end
|
||||
|
||||
def find_has_some(method, *args, &block)
|
||||
method_clean = clean_method method
|
||||
fkc = [method_clean.to_s.pluralize, method_clean.to_s.singularize].inject({}) do |pair, table_name|
|
||||
fkc = begin
|
||||
self.class.connection.foreign_key_constraints(table_name)
|
||||
rescue NotImplementedError
|
||||
nil
|
||||
end
|
||||
pair[table_name] = fkc if not fkc.blank?
|
||||
pair
|
||||
end
|
||||
if not fkc.blank?
|
||||
# assumes there is only one table found - that schema doesn't have a singular and plural table of same name
|
||||
foreign_key = fkc.values.first.find {|fk| fk.reference_table == self.class.table_name}
|
||||
if foreign_key
|
||||
foreign_key = foreign_key.foreign_key
|
||||
table_name = fkc.keys.first
|
||||
klass = Module.const_get table_name.singularize.camelize rescue nil
|
||||
options = {:foreign_key => foreign_key, :class_name => klass.name}
|
||||
end
|
||||
end
|
||||
unless foreign_key
|
||||
klass = Module.const_get method_clean.to_s.downcase.singularize.camelize rescue nil
|
||||
foreign_key = klass.columns.select {|column| column.name == self.class.name.foreign_key}.first if klass
|
||||
end
|
||||
options ||= {}
|
||||
return add_has_some(method, method_clean, options, *args, &block) if foreign_key
|
||||
end
|
||||
|
||||
def add_has_some(method, method_clean, options, *args, &block)
|
||||
association = method_clean.singularize == method_clean ? 'has_one' : 'has_many'
|
||||
self.class.send association, method_clean.to_sym, options rescue puts $!
|
||||
self.send(method, *args, &block)
|
||||
end
|
||||
|
||||
def find_has_some_indirect(method, *args, &block)
|
||||
klass = Module.const_get method.to_s.downcase.singularize.camelize rescue return
|
||||
join_table = nil
|
||||
self.connection.tables.each do |table|
|
||||
unless [self.class.table_name, klass.table_name].include? table
|
||||
columns = self.connection.columns(table).map(&:name)
|
||||
join_table = table if columns.include?(self.class.to_s.foreign_key) and columns.include?(klass.to_s.foreign_key)
|
||||
end
|
||||
break if join_table
|
||||
end
|
||||
return add_has_some_through(join_table, method, *args, &block) if join_table
|
||||
end
|
||||
|
||||
def add_has_some_through(join_table, method, *args, &block)
|
||||
self.class.send 'has_many', method, :through => join_table.to_sym
|
||||
self.send(method, *args, &block)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def clean_method(method)
|
||||
method.to_s.gsub(/=$/,'') # remove any = from the end of the method name
|
||||
end
|
||||
end
|
||||
end
|
||||
270
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/schema.rb
vendored
Normal file
270
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/schema.rb
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
module DrNicMagicModels
|
||||
|
||||
# ONE Schema per namespace module
|
||||
# Person, Company, etc share the Object namespace module, ie. ::Person, ::Company
|
||||
# Blog::Post, Blog::Comment, share the Blog namespace module
|
||||
class Schema
|
||||
attr_reader :modul
|
||||
|
||||
def initialize(modul)
|
||||
@modul = modul
|
||||
@table_name_prefix = modul.instance_variable_get("@table_name_prefix") rescue ''
|
||||
logger.info "Create Schema for #{@modul}, table_name_prefix '#{@table_name_prefix}'"
|
||||
end
|
||||
|
||||
cattr_accessor :inflector
|
||||
cattr_accessor :superklass
|
||||
|
||||
# Need to store models etc per-module, not in @ @models
|
||||
def inflector
|
||||
@inflector ||= Inflector.new
|
||||
end
|
||||
|
||||
# all in lower case please
|
||||
ReservedTables = [:schema_info, :sessions]
|
||||
@models = nil
|
||||
|
||||
def logger
|
||||
@logger ||= DrNicMagicModels::Logger
|
||||
end
|
||||
|
||||
def models
|
||||
load_schema if @models.nil?
|
||||
@models
|
||||
end
|
||||
|
||||
def tables
|
||||
load_schema if @tables.nil?
|
||||
@tables
|
||||
end
|
||||
|
||||
def table_names
|
||||
load_schema if @table_names.nil?
|
||||
@table_names
|
||||
end
|
||||
|
||||
def fks_on_table(table_name)
|
||||
load_schema if @models.nil?
|
||||
@fks_by_table[table_name.to_s] || []
|
||||
end
|
||||
|
||||
# active record only support 2 column link tables, otherwise use a model table, has_many and through
|
||||
def is_link_table?(table_name)
|
||||
load_schema if @models.nil?
|
||||
return @link_tables[table_name] if ! @link_tables[table_name].nil?
|
||||
column_names = @conn.columns(table_name).map{|x| x.name }
|
||||
@link_tables[table_name] = ! column_names.include?("id") && column_names.length == 2 && column_names.select { |x| x =~ /_id$/ } == column_names
|
||||
return @link_tables[table_name]
|
||||
end
|
||||
|
||||
def link_tables_for_class(klass)
|
||||
load_schema if @models.nil?
|
||||
end
|
||||
|
||||
def load_schema(preload = false)
|
||||
return if !@models.nil?
|
||||
|
||||
@superklass ||= ActiveRecord::Base
|
||||
raise "No database connection" if !(@conn = @superklass.connection)
|
||||
|
||||
@models = ModelHash.new
|
||||
@tables = Hash.new
|
||||
@fks_by_table = Hash.new
|
||||
@link_tables = Hash.new
|
||||
|
||||
@table_names = @conn.tables
|
||||
@table_names = @table_names.grep(/^#{@table_name_prefix}/) if @table_name_prefix
|
||||
@table_names = @table_names.sort
|
||||
|
||||
logger.info "For #{modul} tables are #{@table_names.inspect}"
|
||||
|
||||
# Work out which tables are in the model and which aren't
|
||||
@table_names.each do |table_name|
|
||||
|
||||
# deal with reserved tables & link_tables && other stray id-less tables
|
||||
#key = 'id'
|
||||
#case ActiveRecord::Base.primary_key_prefix_type
|
||||
# when :table_name
|
||||
# key = Inflector.foreign_key(table_name, false)
|
||||
# when :table_name_with_underscore
|
||||
# key = Inflector.foreign_key(table_name)
|
||||
#end
|
||||
#next if ReservedTables.include?(table_name.downcase.to_sym) ||
|
||||
# is_link_table?(table_name) ||
|
||||
# ! @conn.columns(table_name).map{ |x| x.name}.include?(key)
|
||||
|
||||
table_name_clean = table_name.gsub(/^#{@table_name_prefix}/,'')
|
||||
|
||||
# a model table then...
|
||||
model_class_name = inflector.class_name(table_name_clean)
|
||||
|
||||
logger.debug "Got a model table: #{table_name} => class #{model_class_name}"
|
||||
|
||||
@models[model_class_name] = table_name
|
||||
@tables[table_name] = model_class_name
|
||||
|
||||
if preload
|
||||
# create by MAGIC!
|
||||
klass = model_class_name.constantize
|
||||
|
||||
# Process FKs?
|
||||
if @conn.supports_fetch_foreign_keys?
|
||||
|
||||
tables.each do |table_name|
|
||||
logger.debug "Getting FKs for #{table_name}"
|
||||
@fks_by_table[table_name] = Array.new
|
||||
@conn.foreign_key_constraints(table_name).each do |fk|
|
||||
logger.debug "Got one: #{fk}"
|
||||
@fks_by_table[table_name].push(fk)
|
||||
end # do each fk
|
||||
|
||||
end # each table
|
||||
end
|
||||
|
||||
# Try to work out our link tables now...
|
||||
@models.keys.sort.each{|klass| process_table(@models[klass.to_s])}
|
||||
@link_tables.keys.sort.each{|table_name| process_link_table(table_name) if @link_tables[table_name]}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def process_table(table_name)
|
||||
|
||||
logger.debug "Processing model table #{table_name}"
|
||||
|
||||
# ok, so let's look at the foreign keys on the table...
|
||||
belongs_to_klass = @tables[table_name].constantize rescue return
|
||||
|
||||
processed_columns = Hash.new
|
||||
|
||||
fks_on_table(table_name).each do |fk|
|
||||
logger.debug "Found FK column by suffix _id [#{fk.foreign_key}]"
|
||||
has_some_klass = Inflector.classify(fk.reference_table).constantize rescue next
|
||||
processed_columns[fk.foreign_key] = { :has_some_klass => has_some_klass }
|
||||
processed_columns[fk.foreign_key].merge! add_has_some_belongs_to(belongs_to_klass, fk.foreign_key, has_some_klass) rescue next
|
||||
end
|
||||
|
||||
column_names = @conn.columns(table_name).map{ |x| x.name}
|
||||
column_names.each do |column_name|
|
||||
next if not column_name =~ /_id$/
|
||||
logger.debug "Found FK column by suffix _id [#{column_name}]"
|
||||
if processed_columns.key?(column_name)
|
||||
logger.debug "Skipping, already processed"
|
||||
next
|
||||
end
|
||||
has_some_klass = Inflector.classify(column_name.sub(/_id$/,"")).constantize rescue next
|
||||
processed_columns[column_name] = { :has_some_klass => has_some_klass }
|
||||
processed_columns[column_name].merge! add_has_some_belongs_to(belongs_to_klass, column_name, has_some_klass) rescue next
|
||||
end
|
||||
|
||||
#TODO: what if same classes in table?
|
||||
|
||||
# is this a link table with attributes? (has_many through?)
|
||||
return if processed_columns.keys.length < 2
|
||||
|
||||
processed_columns.keys.each do |key1|
|
||||
processed_columns.keys.each do |key2|
|
||||
next if key1 == key2
|
||||
logger.debug "\n*** #{processed_columns[key1][:has_some_class]}.send 'has_many', #{processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym}, :through => #{processed_columns[key2][:has_some_name]}\n\n"
|
||||
processed_columns[key1][:has_some_class].send 'has_many', processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym, :through => processed_columns[key2][:has_some_name].to_sym
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def add_has_some_belongs_to(belongs_to_klass, belongs_to_fk, has_some_klass)
|
||||
|
||||
logger.debug "Trying to add a #{belongs_to_klass} belongs_to #{has_some_klass}..."
|
||||
|
||||
# so this is a belongs_to & has_some style relationship...
|
||||
# is it a has_many, or a has_one? Well, let's assume a has_one has a unique index on the column please... good db design, haha!
|
||||
unique = belongs_to_klass.get_unique_index_columns.include?(belongs_to_fk)
|
||||
belongs_to_name = belongs_to_fk.sub(/_id$/, '').to_sym
|
||||
|
||||
logger.debug "\n*** #{belongs_to_klass}.send 'belongs_to', #{belongs_to_name}, :class_name => #{has_some_klass}, :foreign_key => #{belongs_to_fk}\n"
|
||||
belongs_to_klass.send(:belongs_to, belongs_to_name, :class_name => has_some_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
|
||||
|
||||
# work out if we need a prefix
|
||||
has_some_name = (
|
||||
(unique ? belongs_to_klass.table_name.singularize : belongs_to_klass.table_name) +
|
||||
(belongs_to_name.to_s == has_some_klass.table_name.singularize ? "" : "_as_"+belongs_to_name.to_s)
|
||||
).downcase.to_sym
|
||||
method = unique ? :has_one : :has_many
|
||||
logger.debug "\n*** #{has_some_klass}.send(#{method}, #{has_some_name}, :class_name => #{belongs_to_klass.to_s}, :foreign_key => #{belongs_to_fk.to_sym})\n\n"
|
||||
has_some_klass.send(method, has_some_name, :class_name => belongs_to_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
|
||||
|
||||
return { :method => method, :belongs_to_name => belongs_to_name, :has_some_name => has_some_name, :has_some_class => has_some_klass }
|
||||
|
||||
end
|
||||
|
||||
def process_link_table(table_name)
|
||||
|
||||
logger.debug "Processing link table #{table_name}"
|
||||
|
||||
classes_map = Hash.new
|
||||
column_names = @conn.columns(table_name).map{ |x| x.name}
|
||||
|
||||
# use foreign keys first
|
||||
fks_on_table(table_name).each do |fk|
|
||||
logger.debug "Processing fk: #{fk}"
|
||||
klass = Inflector.classify(fk.reference_table).constantize rescue logger.debug("Cannot find model #{class_name} for table #{fk.reference_table}") && return
|
||||
classes_map[fk.foreign_key] = klass
|
||||
end
|
||||
|
||||
logger.debug "Got #{classes_map.keys.length} references from FKs"
|
||||
|
||||
if classes_map.keys.length < 2
|
||||
|
||||
#Fall back on good ol _id recognition
|
||||
|
||||
column_names.each do |column_name|
|
||||
|
||||
# check we haven't processed by fks already
|
||||
next if ! classes_map[column_name].nil?
|
||||
referenced_table = column_name.sub(/_id$/, '')
|
||||
|
||||
begin
|
||||
klass = Inflector.classify(referenced_table).constantize
|
||||
# fall back on FKs here
|
||||
if ! klass.nil?
|
||||
classes_map[column_name] = klass
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# not detected the link table?
|
||||
logger.debug "Got #{classes_map.keys.length} references"
|
||||
logger.debug "Cannot detect both tables referenced in link table" && return if classes_map.keys.length != 2
|
||||
|
||||
logger.debug "Adding habtm relationship"
|
||||
|
||||
logger.debug "\n*** #{classes_map[column_names[0]]}.send 'has_and_belongs_to_many', #{column_names[1].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[1]].to_s}, :join_table => #{table_name.to_sym}\n"
|
||||
logger.debug "\n*** #{classes_map[column_names[1]]}.send 'has_and_belongs_to_many', #{column_names[0].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[0]].to_s}, :join_table => #{table_name.to_sym}\n\n"
|
||||
|
||||
classes_map[column_names[0]].send 'has_and_belongs_to_many', column_names[1].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[1]].to_s, :join_table => table_name.to_sym
|
||||
classes_map[column_names[1]].send 'has_and_belongs_to_many', column_names[0].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[0]].to_s, :join_table => table_name.to_sym
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class ModelHash < Hash
|
||||
def unenquire(class_id)
|
||||
@enquired ||= {}
|
||||
@enquired[class_id = class_id.to_s] = false
|
||||
end
|
||||
|
||||
def enquired?(class_id)
|
||||
@enquired ||= {}
|
||||
@enquired[class_id.to_s]
|
||||
end
|
||||
|
||||
def [](class_id)
|
||||
enquired?(class_id = class_id.to_s)
|
||||
@enquired[class_id] = true
|
||||
super(class_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
46
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/validations.rb
vendored
Normal file
46
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/validations.rb
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
module DrNicMagicModels
|
||||
module Validations
|
||||
|
||||
def generate_validations
|
||||
|
||||
logger = DrNicMagicModels::Logger
|
||||
|
||||
# Ensure that the connection to db is established, else validations don't get created.
|
||||
ActiveRecord::Base.connection
|
||||
|
||||
# Code reworked from http://www.redhillconsulting.com.au/rails_plugins.html
|
||||
# Thanks Red Hill Consulting for using an MIT licence :o)
|
||||
|
||||
# NOT NULL constraints
|
||||
self.columns.reject { |column| column.name =~ /(?i)^(((created|updated)_(at|on))|position|type|id)$/ }.each do |column|
|
||||
|
||||
if column.type == :integer
|
||||
logger.debug "validates_numericality_of #{column.name}, :allow_nil => #{column.null.inspect}, :only_integer => true"
|
||||
self.validates_numericality_of column.name, :allow_nil => column.null, :only_integer => true
|
||||
elsif column.number?
|
||||
logger.debug "validates_numericality_of #{column.name}, :allow_nil => #{column.null.inspect}"
|
||||
self.validates_numericality_of column.name, :allow_nil => column.null
|
||||
elsif column.text? && column.limit
|
||||
logger.debug "validates_length_of #{column.name}, :allow_nil => #{column.null.inspect}, :maximum => #{column.limit}"
|
||||
self.validates_length_of column.name, :allow_nil => column.null, :maximum => column.limit
|
||||
end
|
||||
|
||||
# Active record seems to interpolate booleans anyway to either true, false or nil...
|
||||
if column.type == :boolean
|
||||
logger.debug "validates_inclusion_of #{column.name}, :in => [true, false], :allow_nil => #{column.null}, :message => ActiveRecord::Errors.default_error_messages[:blank]"
|
||||
self.validates_inclusion_of column.name, :in => [true, false], :allow_nil => column.null, :message => ActiveRecord::Errors.default_error_messages[:blank]
|
||||
elsif !column.null
|
||||
logger.debug "validates_presence_of #{column.name}"
|
||||
self.validates_presence_of column.name
|
||||
end
|
||||
end
|
||||
|
||||
# Single-column UNIQUE indexes
|
||||
get_unique_index_columns.each do |col|
|
||||
logger.debug "validates_uniqueness_of #{col}"
|
||||
self.validates_uniqueness_of col
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
9
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/version.rb
vendored
Normal file
9
vendor/gems/dr_nic_magic_models-0.9.2/lib/dr_nic_magic_models/version.rb
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module DrNicMagicModels #:nodoc:
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 0
|
||||
MINOR = 9
|
||||
TINY = 2
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
end
|
||||
33
vendor/gems/dr_nic_magic_models-0.9.2/lib/module.rb
vendored
Normal file
33
vendor/gems/dr_nic_magic_models-0.9.2/lib/module.rb
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
class Module
|
||||
alias :normal_const_missing :const_missing
|
||||
|
||||
def const_missing(class_id)
|
||||
begin
|
||||
return normal_const_missing(class_id)
|
||||
rescue
|
||||
end
|
||||
@magic_schema ||= DrNicMagicModels::Schema.new self
|
||||
unless table_name = @magic_schema.models[class_id]
|
||||
raise NameError.new("uninitialized constant #{class_id}") if @magic_schema.models.enquired? class_id
|
||||
end
|
||||
superklass = @magic_schema.superklass || ActiveRecord::Base
|
||||
klass = create_class(class_id, superklass) do
|
||||
set_table_name table_name
|
||||
# include DrNicMagicModels::MagicModel
|
||||
# extend DrNicMagicModels::Validations
|
||||
end
|
||||
klass.generate_validations # need to call this AFTER the class name has been assigned
|
||||
@magic_schema.inflector.post_class_creation klass
|
||||
klass
|
||||
end
|
||||
|
||||
def magic_module(options)
|
||||
self.instance_variable_set "@table_name_prefix", options[:table_name_prefix] if options[:table_name_prefix]
|
||||
end
|
||||
|
||||
private
|
||||
def create_class(class_name, superclass, &block)
|
||||
klass = Class.new superclass, &block
|
||||
self.const_set class_name, klass
|
||||
end
|
||||
end
|
||||
19
vendor/gems/dr_nic_magic_models-0.9.2/lib/rails.rb
vendored
Normal file
19
vendor/gems/dr_nic_magic_models-0.9.2/lib/rails.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
module Dependencies #:nodoc:#
|
||||
|
||||
@@models_dir = File.expand_path(File.join(RAILS_ROOT,'app','models'))
|
||||
|
||||
# don't reload models... it doesn't work anyway, not sure why they haven't done this?
|
||||
# submit as patch?
|
||||
alias require_or_load_old require_or_load
|
||||
def require_or_load(file_name, *args)
|
||||
file_name = $1 if file_name =~ /^(.*)\.rb$/
|
||||
expanded = File.expand_path(file_name)
|
||||
old_mechanism = Dependencies.mechanism
|
||||
if expanded =~ /^#{@@models_dir}/
|
||||
RAILS_DEFAULT_LOGGER.debug "*** Not reloading #{file_name}"
|
||||
Dependencies.mechanism = :require
|
||||
end
|
||||
require_or_load_old(file_name, *args)
|
||||
Dependencies.mechanism = old_mechanism
|
||||
end
|
||||
end
|
||||
66
vendor/gems/dr_nic_magic_models-0.9.2/scripts/txt2html
vendored
Normal file
66
vendor/gems/dr_nic_magic_models-0.9.2/scripts/txt2html
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'redcloth'
|
||||
require 'syntax/convertors/html'
|
||||
require 'erb'
|
||||
require File.dirname(__FILE__) + '/../lib/dr_nic_magic_models/version.rb'
|
||||
|
||||
version = DrNicMagicModels::VERSION::STRING
|
||||
download = 'http://rubyforge.org/projects/magicmodels'
|
||||
|
||||
class Fixnum
|
||||
def ordinal
|
||||
# teens
|
||||
return 'th' if (10..19).include?(self % 100)
|
||||
# others
|
||||
case self % 10
|
||||
when 1: return 'st'
|
||||
when 2: return 'nd'
|
||||
when 3: return 'rd'
|
||||
else return 'th'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Time
|
||||
def pretty
|
||||
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_syntax(syntax, source)
|
||||
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
||||
end
|
||||
|
||||
if ARGV.length >= 1
|
||||
src, template = ARGV
|
||||
template ||= File.dirname(__FILE__) + '/../website/template.rhtml'
|
||||
else
|
||||
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
||||
exit!
|
||||
end
|
||||
|
||||
template = ERB.new(File.open(template).read)
|
||||
|
||||
title = nil
|
||||
body = nil
|
||||
File.open(src) do |fsrc|
|
||||
title_text = fsrc.readline
|
||||
body_text = fsrc.read
|
||||
syntax_items = []
|
||||
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
||||
ident = syntax_items.length
|
||||
element, syntax, source = $1, $2, $3
|
||||
syntax_items << "<#{element} class=\"syntax\">#{convert_syntax(syntax, source)}</#{element}>"
|
||||
"syntax-temp-#{ident}"
|
||||
}
|
||||
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
||||
body = RedCloth.new(body_text).to_html
|
||||
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
||||
end
|
||||
stat = File.stat(src)
|
||||
created = stat.ctime
|
||||
modified = stat.mtime
|
||||
|
||||
$stdout << template.result(binding)
|
||||
58
vendor/gems/dr_nic_magic_models-0.9.2/scripts/txt2js
vendored
Normal file
58
vendor/gems/dr_nic_magic_models-0.9.2/scripts/txt2js
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'redcloth'
|
||||
require 'syntax/convertors/html'
|
||||
require 'erb'
|
||||
require 'active_support'
|
||||
require File.dirname(__FILE__) + '/../lib/dr_nic_magic_models/version.rb'
|
||||
|
||||
version = DrNicMagicModels::VERSION::STRING
|
||||
download = 'http://rubyforge.org/projects/magicmodels'
|
||||
|
||||
class Fixnum
|
||||
def ordinal
|
||||
# teens
|
||||
return 'th' if (10..19).include?(self % 100)
|
||||
# others
|
||||
case self % 10
|
||||
when 1: return 'st'
|
||||
when 2: return 'nd'
|
||||
when 3: return 'rd'
|
||||
else return 'th'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Time
|
||||
def pretty
|
||||
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_syntax(syntax, source)
|
||||
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
||||
end
|
||||
|
||||
if ARGV.length >= 1
|
||||
src, template = ARGV
|
||||
template ||= File.dirname(__FILE__) + '/../website/template.js'
|
||||
else
|
||||
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
||||
exit!
|
||||
end
|
||||
|
||||
template = ERB.new(File.open(template).read)
|
||||
|
||||
title = nil
|
||||
body = nil
|
||||
File.open(src) do |fsrc|
|
||||
title_text = fsrc.readline
|
||||
body = fsrc.read
|
||||
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
||||
end
|
||||
stat = File.stat(src)
|
||||
created = stat.ctime
|
||||
modified = stat.mtime
|
||||
|
||||
$stdout << template.result(binding)
|
||||
BIN
vendor/gems/dr_nic_magic_models-0.9.2/test.db
vendored
Normal file
BIN
vendor/gems/dr_nic_magic_models-0.9.2/test.db
vendored
Normal file
Binary file not shown.
72
vendor/gems/dr_nic_magic_models-0.9.2/test/abstract_unit.rb
vendored
Normal file
72
vendor/gems/dr_nic_magic_models-0.9.2/test/abstract_unit.rb
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
require 'active_record'
|
||||
require 'active_record/fixtures'
|
||||
require 'active_support/binding_of_caller'
|
||||
require 'active_support/breakpoint'
|
||||
require 'connection'
|
||||
require 'dr_nic_magic_models'
|
||||
|
||||
ActiveSupport::Deprecation.debug = true
|
||||
|
||||
|
||||
QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Object.const_defined?(:QUOTED_TYPE)
|
||||
|
||||
class Test::Unit::TestCase #:nodoc:
|
||||
self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
||||
self.use_instantiated_fixtures = false
|
||||
self.use_transactional_fixtures = true #(ENV['AR_NO_TX_FIXTURES'] != "yes")
|
||||
|
||||
def create_fixtures(*table_names, &block)
|
||||
Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names, {}, &block)
|
||||
end
|
||||
|
||||
def assert_date_from_db(expected, actual, message = nil)
|
||||
# SQL Server doesn't have a separate column type just for dates,
|
||||
# so the time is in the string and incorrectly formatted
|
||||
if current_adapter?(:SQLServerAdapter)
|
||||
assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
|
||||
elsif current_adapter?(:SybaseAdapter)
|
||||
assert_equal expected.to_s, actual.to_date.to_s, message
|
||||
else
|
||||
assert_equal expected.to_s, actual.to_s, message
|
||||
end
|
||||
end
|
||||
|
||||
def assert_queries(num = 1)
|
||||
ActiveRecord::Base.connection.class.class_eval do
|
||||
self.query_count = 0
|
||||
alias_method :execute, :execute_with_query_counting
|
||||
end
|
||||
yield
|
||||
ensure
|
||||
ActiveRecord::Base.connection.class.class_eval do
|
||||
alias_method :execute, :execute_without_query_counting
|
||||
end
|
||||
assert_equal num, ActiveRecord::Base.connection.query_count, "#{ActiveRecord::Base.connection.query_count} instead of #{num} queries were executed."
|
||||
end
|
||||
|
||||
def assert_no_queries(&block)
|
||||
assert_queries(0, &block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def current_adapter?(type)
|
||||
ActiveRecord::ConnectionAdapters.const_defined?(type) &&
|
||||
ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type))
|
||||
end
|
||||
|
||||
ActiveRecord::Base.connection.class.class_eval do
|
||||
cattr_accessor :query_count
|
||||
alias_method :execute_without_query_counting, :execute
|
||||
def execute_with_query_counting(sql, name = nil)
|
||||
self.query_count += 1
|
||||
execute_without_query_counting(sql, name)
|
||||
end
|
||||
end
|
||||
|
||||
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||
#ActiveRecord::Base.colorize_logging = false
|
||||
13
vendor/gems/dr_nic_magic_models-0.9.2/test/connections/native_mysql/connection.rb
vendored
Normal file
13
vendor/gems/dr_nic_magic_models-0.9.2/test/connections/native_mysql/connection.rb
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
print "Using native MySQL\n"
|
||||
require 'logger'
|
||||
|
||||
ActiveRecord::Base.logger = Logger.new("debug.log")
|
||||
|
||||
db1 = "dr_nic_magic_models_unittest"
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
:adapter => "mysql",
|
||||
:username => "root",
|
||||
:encoding => "utf8",
|
||||
:database => db1
|
||||
)
|
||||
12
vendor/gems/dr_nic_magic_models-0.9.2/test/connections/native_postgresql/connection.rb
vendored
Normal file
12
vendor/gems/dr_nic_magic_models-0.9.2/test/connections/native_postgresql/connection.rb
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
print "Using Postgres\n"
|
||||
require 'logger'
|
||||
|
||||
ActiveRecord::Base.logger = Logger.new("debug.log")
|
||||
|
||||
db1 = "dr_nic_magic_models_unittest"
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
:adapter => "postgresql",
|
||||
:encoding => "utf8",
|
||||
:database => db1
|
||||
)
|
||||
10
vendor/gems/dr_nic_magic_models-0.9.2/test/connections/native_sqlite/connection.rb
vendored
Normal file
10
vendor/gems/dr_nic_magic_models-0.9.2/test/connections/native_sqlite/connection.rb
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
print "Using native Sqlite3\n"
|
||||
require 'logger'
|
||||
|
||||
ActiveRecord::Base.logger = Logger.new("debug.log")
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
:adapter => "sqlite3",
|
||||
:dbfile => "test.db"
|
||||
)
|
||||
|
||||
13
vendor/gems/dr_nic_magic_models-0.9.2/test/dummy_test.rb
vendored
Normal file
13
vendor/gems/dr_nic_magic_models-0.9.2/test/dummy_test.rb
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'abstract_unit'
|
||||
#require 'fixtures/user'
|
||||
#require 'fixtures/group'
|
||||
#require 'fixtures/membership'
|
||||
|
||||
class DummyTest < Test::Unit::TestCase
|
||||
def setup
|
||||
end
|
||||
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
||||
10
vendor/gems/dr_nic_magic_models-0.9.2/test/env_test.rb
vendored
Normal file
10
vendor/gems/dr_nic_magic_models-0.9.2/test/env_test.rb
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
class EnvTest < Test::Unit::TestCase
|
||||
|
||||
def test_modules
|
||||
assert_not_nil DrNicMagicModels
|
||||
assert_not_nil DrNicMagicModels::Validations
|
||||
assert_not_nil DrNicMagicModels::Schema
|
||||
end
|
||||
end
|
||||
3
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/adjectives.yml
vendored
Normal file
3
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/adjectives.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
first:
|
||||
id: 1
|
||||
name: kind
|
||||
3
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/adjectives_fun_users.yml
vendored
Normal file
3
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/adjectives_fun_users.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
first:
|
||||
fun_user_id: 1
|
||||
adjective_id: 1
|
||||
4
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/mysql.drop.sql
vendored
Normal file
4
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/mysql.drop.sql
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
DROP TABLE fun_users;
|
||||
DROP TABLE groups;
|
||||
DROP TABLE group_memberships;
|
||||
DROP TABLE group_tag;
|
||||
56
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/mysql.sql
vendored
Normal file
56
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/mysql.sql
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
CREATE TABLE `fun_users` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`type` varchar(255) NOT NULL,
|
||||
`firstname` varchar(50) NOT NULL,
|
||||
`lastname` varchar(50) NOT NULL,
|
||||
`login` varchar(50) NOT NULL,
|
||||
`email` varchar(50) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `groups` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`name` varchar(50) NOT NULL UNIQUE,
|
||||
`description` varchar(50) default NULL,
|
||||
`some_int` integer default NULL,
|
||||
`some_float` float default NULL,
|
||||
`some_bool` boolean default NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `group_memberships` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`fun_user_id` int(11) NOT NULL,
|
||||
`group_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `adjectives` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`name` varchar(255),
|
||||
PRIMARY KEY (`id`)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
CREATE TABLE `adjectives_fun_users` (
|
||||
`fun_user_id` int(11) NOT NULL,
|
||||
`adjective_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`fun_user_id`,`adjective_id`)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
|
||||
CREATE TABLE `group_tag` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`name` varchar(50) NOT NULL,
|
||||
`group_id` int(11) NOT NULL,
|
||||
`referenced_group_id` int(11) NULL UNIQUE,
|
||||
PRIMARY KEY (`id`)
|
||||
) TYPE=InnoDB;
|
||||
|
||||
ALTER TABLE `group_tag`
|
||||
ADD FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE `group_tag`
|
||||
ADD FOREIGN KEY (`referenced_group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE `adjectives_fun_users`
|
||||
ADD FOREIGN KEY (`adjective_id`) REFERENCES `adjectives` (`id`) ON DELETE CASCADE;
|
||||
55
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/postgresql.sql
vendored
Normal file
55
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/postgresql.sql
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
CREATE TABLE "fun_users" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"type" varchar(255) NOT NULL,
|
||||
"firstname" varchar(50) NOT NULL,
|
||||
"lastname" varchar(50) NOT NULL,
|
||||
"login" varchar(50) NOT NULL,
|
||||
"email" varchar(50) NULL,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "groups" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" varchar(50) NOT NULL UNIQUE,
|
||||
"description" varchar(50) default NULL,
|
||||
"some_int" integer default NULL,
|
||||
"some_float" float default NULL,
|
||||
"some_bool" boolean default NULL,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "group_memberships" (
|
||||
"id" SERIAL,
|
||||
"fun_user_id" int NOT NULL,
|
||||
"group_id" int NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "adjectives" (
|
||||
"id" SERIAL,
|
||||
"name" varchar(255),
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "adjectives_fun_users" (
|
||||
"fun_user_id" int NOT NULL,
|
||||
"adjective_id" int NOT NULL,
|
||||
PRIMARY KEY ("fun_user_id","adjective_id")
|
||||
);
|
||||
|
||||
CREATE TABLE "group_tag" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" varchar(50) NOT NULL,
|
||||
"group_id" int NOT NULL,
|
||||
"referenced_group_id" int NULL UNIQUE,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
ALTER TABLE "group_tag"
|
||||
ADD FOREIGN KEY ("group_id") REFERENCES "groups" ("id") ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE "group_tag"
|
||||
ADD FOREIGN KEY ("referenced_group_id") REFERENCES "groups" ("id") ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE "adjectives_fun_users"
|
||||
ADD FOREIGN KEY ("adjective_id") REFERENCES "adjectives" ("id") ON DELETE CASCADE;
|
||||
49
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/sqlite.sql
vendored
Normal file
49
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/db_definitions/sqlite.sql
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
CREATE TABLE `fun_users` (
|
||||
`id` int(11) NOT NULL,
|
||||
`type` varchar(255) NOT NULL,
|
||||
`firstname` varchar(50) NOT NULL,
|
||||
`lastname` varchar(50) NOT NULL,
|
||||
`login` varchar(50) NOT NULL,
|
||||
`email` varchar(50) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `groups` (
|
||||
`id` int(11) NOT NULL ,
|
||||
`name` varchar(50) NOT NULL UNIQUE,
|
||||
`description` varchar(50) default NULL,
|
||||
`some_int` integer default NULL,
|
||||
`some_float` float default NULL,
|
||||
`some_bool` boolean default NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `group_memberships` (
|
||||
`id` int(11) NOT NULL,
|
||||
`fun_user_id` int(11) NOT NULL,
|
||||
`group_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `adjectives` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(255),
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `adjectives_fun_users` (
|
||||
`fun_user_id` int(11) NOT NULL,
|
||||
`adjective_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`fun_user_id`,`adjective_id`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `group_tag` (
|
||||
`id` int(11) NOT NULL,
|
||||
`name` varchar(50) NOT NULL,
|
||||
`group_id` int(11) NOT NULL,
|
||||
`referenced_group_id` int(11) NULL UNIQUE,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
|
||||
14
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/fun_users.yml
vendored
Normal file
14
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/fun_users.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
first:
|
||||
id: 1
|
||||
firstname: First
|
||||
lastname: Person
|
||||
login: first
|
||||
email: first@person.com
|
||||
type: FunUser
|
||||
second:
|
||||
id: 2
|
||||
firstname: Second
|
||||
lastname: Person
|
||||
login: sec
|
||||
email: sec@person.com
|
||||
type: FunUserPlus
|
||||
4
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/group_memberships.yml
vendored
Normal file
4
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/group_memberships.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
first_first:
|
||||
id: 1
|
||||
group_id: 1
|
||||
fun_user_id: 1
|
||||
11
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/group_tag.yml
vendored
Normal file
11
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/group_tag.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
first:
|
||||
id: 1
|
||||
name: Test
|
||||
group_id: 1
|
||||
referenced_group_id: 1
|
||||
second:
|
||||
id: 2
|
||||
name: Also Test
|
||||
group_id: 1
|
||||
referenced_group_id: NULL
|
||||
|
||||
12
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/groups.yml
vendored
Normal file
12
vendor/gems/dr_nic_magic_models-0.9.2/test/fixtures/groups.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
first:
|
||||
id: 1
|
||||
name: Group One
|
||||
description: First group
|
||||
other:
|
||||
id: 2
|
||||
name: Group Plus
|
||||
description: Extended Group
|
||||
other:
|
||||
id: 2
|
||||
name: Group Plus
|
||||
description: Extended Group
|
||||
0
vendor/gems/dr_nic_magic_models-0.9.2/test/foreign_keys_test.rb
vendored
Normal file
0
vendor/gems/dr_nic_magic_models-0.9.2/test/foreign_keys_test.rb
vendored
Normal file
2
vendor/gems/dr_nic_magic_models-0.9.2/test/fun_user_plus.rb
vendored
Normal file
2
vendor/gems/dr_nic_magic_models-0.9.2/test/fun_user_plus.rb
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
class FunUserPlus < FunUser
|
||||
end
|
||||
71
vendor/gems/dr_nic_magic_models-0.9.2/test/invisible_model_access_test.rb
vendored
Normal file
71
vendor/gems/dr_nic_magic_models-0.9.2/test/invisible_model_access_test.rb
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
require 'abstract_unit'
|
||||
require 'pp'
|
||||
|
||||
class InvisibleModelAccessTest < Test::Unit::TestCase
|
||||
# fixtures :fun_users, :groups, :group_memberships, :group_tag
|
||||
|
||||
def setup
|
||||
create_fixtures :fun_users, :groups, :group_memberships, :group_tag
|
||||
@classes = [FunUser, Group, GroupMembership, GroupTag]
|
||||
@group = Group.find(:first)
|
||||
end
|
||||
|
||||
def test_attributes
|
||||
assert_not_nil @group.name
|
||||
end
|
||||
|
||||
def test_find
|
||||
@classes.each do |klass|
|
||||
assert_not_nil obj = klass.find(1)
|
||||
assert_equal klass, obj.class
|
||||
end
|
||||
end
|
||||
|
||||
def test_sti
|
||||
require 'fun_user_plus'
|
||||
x = FunUserPlus.find(:all)
|
||||
assert x.inject {|n,v| n &= v.class == FunUserPlus}, "Wrong object class in FunUserPlus.find(:all)"
|
||||
plus = x.first
|
||||
assert_not_nil plus
|
||||
assert plus.is_a?(FunUser)
|
||||
assert plus.class == FunUserPlus
|
||||
end
|
||||
|
||||
def test_new
|
||||
assert group = Group.new(:name => 'New Group')
|
||||
assert_equal Group, group.class
|
||||
end
|
||||
|
||||
def test_update
|
||||
assert @group.update_attributes(:name => 'Group 1'), "Couldn't update:\n#{str=""; @group.errors.each_full { |msg| str += "#{msg}\n" }; str }"
|
||||
end
|
||||
|
||||
def test_delete
|
||||
assert @group.destroy
|
||||
end
|
||||
|
||||
def test_validations
|
||||
group = Group.new
|
||||
group.description = "x"*100
|
||||
group.some_int = 99.9
|
||||
group.some_float = "bah"
|
||||
# Active record seems to interpolate booleans anyway to either true, false or nil...
|
||||
# group.some_bool = "xxx" => false (!)
|
||||
|
||||
assert !group.valid?, "Group should not be valid"
|
||||
[:name, :description, :some_int, :some_float].each do |x|
|
||||
assert_not_nil group.errors[x], "Failed on #{x}=[#{group.send(x)}], it should be invalid"
|
||||
end
|
||||
|
||||
group = Group.new
|
||||
group.name = "name"
|
||||
group.description = "x"*49
|
||||
group.some_int = 99
|
||||
group.some_float = 99.9
|
||||
group.some_bool = true
|
||||
assert group.valid?, "Group should be valid"
|
||||
|
||||
group.name = @group.name
|
||||
assert !group.valid?, "Groups should have unique names"
|
||||
end
|
||||
end
|
||||
61
vendor/gems/dr_nic_magic_models-0.9.2/test/invisible_model_assoc_test.rb
vendored
Normal file
61
vendor/gems/dr_nic_magic_models-0.9.2/test/invisible_model_assoc_test.rb
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
class InvisibleModelAssocTest < Test::Unit::TestCase
|
||||
# fixtures :fun_users, :groups, :group_memberships, :group_tag, :adjectives, :adjectives_fun_users
|
||||
|
||||
def setup
|
||||
create_fixtures :fun_users, :groups, :group_memberships, :group_tag, :adjectives, :adjectives_fun_users
|
||||
@group = Group.find(1)
|
||||
@group_tag = GroupTag.find(1)
|
||||
@user = FunUser.find(1)
|
||||
@membership = GroupMembership.find(1)
|
||||
end
|
||||
|
||||
def test_hatbm
|
||||
assert_equal([Adjective.find(1)], @user.adjectives)
|
||||
end
|
||||
|
||||
def test_fk
|
||||
|
||||
gt = GroupTag.find(1)
|
||||
|
||||
# Not using FKs
|
||||
g = gt.group
|
||||
assert g.class == Group
|
||||
assert g.id == 1
|
||||
|
||||
# Using FKs
|
||||
if g.connection.supports_fetch_foreign_keys?
|
||||
g = gt.referenced_group
|
||||
assert g.class == Group
|
||||
assert g.id == 1
|
||||
end
|
||||
end
|
||||
|
||||
def test_has_many
|
||||
assert_equal [@membership], @group.group_memberships
|
||||
assert_equal @group, @membership.group
|
||||
end
|
||||
|
||||
def test_has_one
|
||||
if @group_tag.connection.supports_fetch_foreign_keys?
|
||||
assert_equal @group, @group_tag.referenced_group
|
||||
# assert_equal @group_tag, @group.group_tag_as_referenced_group
|
||||
end
|
||||
end
|
||||
|
||||
def test_belongs_to
|
||||
assert_equal @user, @membership.fun_user
|
||||
assert_equal @group, @membership.group
|
||||
manual_result = GroupTag.find(:all, :conditions => ['group_tag.group_id = ?', @group.id]) #.sort{|a,b| a.id <=> b.id}
|
||||
auto_result = @group.group_tags #.sort{|a,b| a.id <=> b.id}
|
||||
assert manual_result == auto_result, "[#{manual_result.join(',')}] != [#{auto_result.join(',')}]"
|
||||
|
||||
end
|
||||
|
||||
def test_indirect
|
||||
assert_equal [@user], @group.fun_users
|
||||
assert_equal [@group], @user.groups
|
||||
end
|
||||
|
||||
end
|
||||
23
vendor/gems/dr_nic_magic_models-0.9.2/test/invisible_model_classes_test.rb
vendored
Normal file
23
vendor/gems/dr_nic_magic_models-0.9.2/test/invisible_model_classes_test.rb
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
class InvisibleModelClassesTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
|
||||
end
|
||||
|
||||
def test_available
|
||||
assert_not_nil Group
|
||||
assert_not_nil FunUser
|
||||
assert_not_nil GroupMembership
|
||||
assert_not_nil GroupTag, "Could not find GroupTag with singularized table name 'GroupTag'"
|
||||
end
|
||||
|
||||
def test_table_names
|
||||
assert_equal 'groups', Group.table_name
|
||||
assert_equal 'fun_users', FunUser.table_name
|
||||
assert_equal 'group_memberships', GroupMembership.table_name
|
||||
assert_equal 'group_tag', GroupTag.table_name
|
||||
end
|
||||
|
||||
end
|
||||
20
vendor/gems/dr_nic_magic_models-0.9.2/test/magic_module_test.rb
vendored
Normal file
20
vendor/gems/dr_nic_magic_models-0.9.2/test/magic_module_test.rb
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'abstract_unit'
|
||||
|
||||
module MagicGroup
|
||||
magic_module :table_name_prefix => 'group_'
|
||||
end
|
||||
|
||||
class MagicModuleTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
|
||||
end
|
||||
|
||||
def test_table_prefix
|
||||
assert_nothing_thrown { MagicGroup::Membership }
|
||||
assert_equal('group_memberships', MagicGroup::Membership.table_name)
|
||||
assert_nothing_thrown { MagicGroup::Tag }
|
||||
assert_equal('group_tag', MagicGroup::Tag.table_name)
|
||||
end
|
||||
|
||||
end
|
||||
20
vendor/gems/dr_nic_magic_models-0.9.2/test/test_existing_model.rb
vendored
Normal file
20
vendor/gems/dr_nic_magic_models-0.9.2/test/test_existing_model.rb
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'abstract_unit'
|
||||
require 'pp'
|
||||
|
||||
module TestBed
|
||||
class Group < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
end
|
||||
|
||||
class TestExistingModel < Test::Unit::TestCase
|
||||
# fixtures :fun_users, :groups, :group_memberships, :group_tag
|
||||
|
||||
def setup
|
||||
create_fixtures :fun_users, :groups, :group_memberships, :group_tag
|
||||
end
|
||||
|
||||
def test_valid
|
||||
assert(!TestBed::Group.new.valid?)
|
||||
end
|
||||
end
|
||||
404
vendor/gems/dr_nic_magic_models-0.9.2/website/index.html
vendored
Normal file
404
vendor/gems/dr_nic_magic_models-0.9.2/website/index.html
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>
|
||||
Dr Nic’s Magic Models
|
||||
</title>
|
||||
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="version-raw.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
settings = {
|
||||
tl: { radius: 10 },
|
||||
tr: { radius: 10 },
|
||||
bl: { radius: 10 },
|
||||
br: { radius: 10 },
|
||||
antiAlias: true,
|
||||
autoPad: true,
|
||||
validTags: ["div"]
|
||||
}
|
||||
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
||||
versionBox.applyCornersToAll();
|
||||
|
||||
document.getElementById("version_num").innerHTML = version;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<p><a href="/">↩ More Magic</a></p>
|
||||
|
||||
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/magicmodels"; return false'>
|
||||
Get Version
|
||||
<a id="version_num" href="http://rubyforge.org/projects/magicmodels" class="numbers"></a>
|
||||
</div>
|
||||
<h1>Dr Nic’s Magic Models</h1>
|
||||
<p>If you’ve used Ruby on Rails you’ll have written at least one model class like this:</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="keyword">class </span><span class="class">Person</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="ident">has_many</span> <span class="symbol">:memberships</span>
|
||||
<span class="ident">has_many</span> <span class="symbol">:groups</span><span class="punct">,</span> <span class="symbol">:through</span> <span class="punct">=></span> <span class="symbol">:memberships</span>
|
||||
<span class="ident">belongs_to</span> <span class="symbol">:family</span>
|
||||
<span class="ident">validates_presence_of</span> <span class="symbol">:firstname</span><span class="punct">,</span> <span class="symbol">:lastname</span><span class="punct">,</span> <span class="symbol">:email</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>A few minutes later you’ll have wondered to yourself,</p>
|
||||
|
||||
|
||||
<blockquote>
|
||||
Why do I have write my own <code>has_many</code>, <code>belongs_to</code>, and <code>validates_presence_of</code>
|
||||
commands if all the data is in the database schema?
|
||||
</blockquote>
|
||||
|
||||
<p>Now, for the very first time, your classes can look like this:</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="keyword">class </span><span class="class">Person</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>or, if you are lazy…</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="keyword">class </span><span class="class">Person</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span><span class="punct">;</span> <span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>or, if you read right to the end of this page, this…</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="comment"># Go fish.</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>Magic and mystery abound. All for you. Impress your friends, amaze your mother.</p>
|
||||
|
||||
|
||||
<p><span class="caps">NOTE</span>: The gratuitous use of <strong>Dr Nic’s</strong> in the name should only enhance the mystical magikery,
|
||||
for magic needs a magician; and I love magic. I always wanted to create my own magic trick.
|
||||
So I shall be the magician for the sake of magic itself. I look a bit like Harry Potter too,
|
||||
if Harry were 32 and better dressed.</p>
|
||||
|
||||
|
||||
<h2>Installation</h2>
|
||||
|
||||
|
||||
To install the Dr Nic’s Magic Models gem you can run the following command to
|
||||
fetch the gem remotely from RubyForge:
|
||||
<pre>
|
||||
gem install dr_nic_magic_models
|
||||
</pre>
|
||||
|
||||
<p>or <a href="http://rubyforge.org/projects/magicmodels">download the gem manually</a> and
|
||||
run the above command in the download directory.</p>
|
||||
|
||||
|
||||
<p>Now you need to <code>require</code> the gem into your Ruby/Rails app. Insert the following
|
||||
line into your script (use <code>config/environment.rb</code> for your Rails apps):</p>
|
||||
|
||||
|
||||
<pre>
|
||||
require 'dr_nic_magic_models'
|
||||
</pre>
|
||||
|
||||
<p>Your application is now blessed with magical mystery.</p>
|
||||
|
||||
|
||||
<h2>David Copperfield eat your Ruby-crusted heart out</h2>
|
||||
|
||||
|
||||
<p>Let’s demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app (example uses sqlite3, but use your favourite databas):</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="ident">rails</span> <span class="ident">magic_show</span> <span class="punct">-</span><span class="ident">d</span> <span class="ident">sqlite3</span>
|
||||
<span class="ident">cd</span> <span class="ident">magic_show</span>
|
||||
<span class="ident">ruby</span> <span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">model</span> <span class="constant">Person</span>
|
||||
<span class="ident">ruby</span> <span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">model</span> <span class="constant">Group</span>
|
||||
<span class="ident">ruby</span> <span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">model</span> <span class="constant">Membership</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>Update the migration <code>001_create_people.rb</code> with:
|
||||
<pre class="syntax">
|
||||
<span class="keyword">class </span><span class="class">CreatePeople</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span>
|
||||
<span class="keyword">def </span><span class="method">self.up</span>
|
||||
<span class="ident">create_table</span> <span class="symbol">:people</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:firstname</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:lastname</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:email</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="keyword">end</span>
|
||||
<span class="keyword">end</span>
|
||||
|
||||
<span class="keyword">def </span><span class="method">self.down</span>
|
||||
<span class="ident">drop_table</span> <span class="symbol">:people</span>
|
||||
<span class="keyword">end</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>Similarly, update the <code>def self.up</code> method of <code>002_create_groups.rb</code>
|
||||
with:
|
||||
<pre class="syntax">
|
||||
<span class="ident">create_table</span> <span class="symbol">:groups</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:name</span><span class="punct">,</span> <span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:description</span><span class="punct">,</span> <span class="symbol">:string</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>and <code>003_create_memberships.rb</code> with:
|
||||
<pre class="syntax">
|
||||
<span class="ident">create_table</span> <span class="symbol">:memberships</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:person_id</span><span class="punct">,</span> <span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:group_id</span><span class="punct">,</span> <span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:null</span> <span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
And run your migrations to create the three tables:
|
||||
<pre>
|
||||
rake db:migrate
|
||||
</pre>
|
||||
|
||||
<h3>And now for some <a href="http://en.wikipedia.org/wiki/List_of_conjuring_terms">woofle dust</a> ...</h3>
|
||||
|
||||
|
||||
<p>At the end of <code>config/environment.rb</code> add the following line:</p>
|
||||
|
||||
|
||||
<pre>
|
||||
require 'dr_nic_magic_models'
|
||||
</pre>
|
||||
|
||||
<p>Now, let’s do a magic trick. First, let’s check our model classes (<code>app/models/person.rb</code> etc):</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="keyword">class </span><span class="class">Person</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="keyword">end</span>
|
||||
<span class="keyword">class </span><span class="class">Group</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="keyword">end</span>
|
||||
<span class="keyword">class </span><span class="class">Membership</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.</p>
|
||||
|
||||
|
||||
<p><span class="caps">UPDATE</span>: To turn on magic validations, you now need to invoke <code>generate_validations</code> on defined classes. So, update your model classes:</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="keyword">class </span><span class="class">Person</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="ident">generate_validations</span>
|
||||
<span class="keyword">end</span>
|
||||
<span class="keyword">class </span><span class="class">Group</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="ident">generate_validations</span>
|
||||
<span class="keyword">end</span>
|
||||
<span class="keyword">class </span><span class="class">Membership</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
|
||||
<span class="ident">generate_validations</span>
|
||||
<span class="keyword">end</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>For this trick, we’ll need an ordinary console session. Any old one lying around the house will do.</p>
|
||||
|
||||
|
||||
<pre>
|
||||
ruby script/console
|
||||
</pre>
|
||||
|
||||
<p>Now a normal model class is valid until you explicitly add <code>validates_xxx</code> commands.
|
||||
With Dr Nic’s Magic Models:</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">new</span>
|
||||
<span class="punct">=></span> <span class="comment">#<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true></span>
|
||||
<span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
|
||||
<span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="ident">person</span><span class="punct">.</span><span class="ident">errors</span>
|
||||
<span class="punct">=></span> <span class="comment">#<ActiveRecord::Errors:0x3537b38 @errors={</span>
|
||||
<span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>["</span><span class="string">can't be blank</span><span class="punct">",</span> <span class="punct">"</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">"],</span>
|
||||
<span class="punct">"</span><span class="string">lastname</span><span class="punct">"=>["</span><span class="string">can't be blank</span><span class="punct">",</span> <span class="punct">"</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">"],</span>
|
||||
<span class="punct">"</span><span class="string">email</span><span class="punct">"=>["</span><span class="string">can't be blank</span><span class="punct">",</span> <span class="punct">"</span><span class="string">is too long (maximum is 255 characters)</span><span class="punct">"]},</span>
|
||||
<span class="attribute">@base</span><span class="punct">=</span><span class="comment">#<Person:0x3538bf0 @errors=#<ActiveRecord::Errors:0x3537b38 ...>, @new_record=true, </span>
|
||||
<span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">,</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">,</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">}>></span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p><strong>Kapoow!</strong> Instant validation! (NOTE: not as instant as it used to be – remember – you need to call <code>generate_validations</code> on each class as required)</p>
|
||||
|
||||
|
||||
<p>Because you specified the three columns as <code>:null => false</code>,
|
||||
your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
|
||||
for each non-null field, plus several other validations (since version 0.8.0).</p>
|
||||
|
||||
|
||||
<p>Ok, we’re just warming up.</p>
|
||||
|
||||
|
||||
<p>Your models normally require association commands (<code>has_many</code>, <code>belongs_to</code>, etc, as
|
||||
demonstrated above) to have the brilliantly simple support that Rails/ActiveRecords are known for.</p>
|
||||
|
||||
|
||||
<p>Let’s just watch what Dr Nic’s Magic Models can do without any effort at all…</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(</span><span class="symbol">:firstname</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">Nic</span><span class="punct">",</span> <span class="symbol">:lastname</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">Williams</span><span class="punct">",</span> <span class="symbol">:email</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">")</span>
|
||||
<span class="ident">group</span> <span class="punct">=</span> <span class="constant">Group</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(</span><span class="symbol">:name</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">Magic Models Forum</span><span class="punct">",</span> <span class="symbol">:description</span> <span class="punct">=></span> <span class="punct">"</span><span class="string">http://groups.google.com/magicmodels</span><span class="punct">")</span>
|
||||
<span class="ident">membership</span> <span class="punct">=</span> <span class="constant">Membership</span><span class="punct">.</span><span class="ident">create</span><span class="punct">(</span><span class="symbol">:person</span> <span class="punct">=></span> <span class="ident">person</span><span class="punct">,</span> <span class="symbol">:group</span> <span class="punct">=></span> <span class="ident">group</span><span class="punct">)</span>
|
||||
<span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span><span class="punct">.</span><span class="ident">length</span>
|
||||
<span class="punct">=></span> <span class="number">1</span>
|
||||
<span class="ident">membership</span><span class="punct">.</span><span class="ident">person</span>
|
||||
<span class="punct">=></span> <span class="punct"><</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x38898e8</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=>"</span><span class="string">Williams</span><span class="punct">",</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>"</span><span class="string">Nic</span><span class="punct">",</span>
|
||||
<span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=>"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">"}></span>
|
||||
<span class="ident">group</span><span class="punct">.</span><span class="ident">memberships</span>
|
||||
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x3c8cd70</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">group_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">person_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">"}>]</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>That final association trick is a ripper. Automatic generation of <code>has_many :through</code> associations…</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="punct">>></span> <span class="ident">person</span><span class="punct">.</span><span class="ident">groups</span>
|
||||
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Group</span><span class="punct">:</span><span class="number">0x39047e0</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">name</span><span class="punct">"=>"</span><span class="string">Magic Models Forum</span><span class="punct">",</span> <span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">description</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">}>]</span>
|
||||
<span class="punct">>></span> <span class="ident">group</span><span class="punct">.</span><span class="ident">people</span>
|
||||
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x3c33580</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=>"</span><span class="string">Williams</span><span class="punct">",</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>"</span><span class="string">Nic</span><span class="punct">",</span>
|
||||
<span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=>"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">"}>]</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<h3>Drum roll…</h3>
|
||||
|
||||
|
||||
<p>Ladies and gentlemen. For my final feat of magical mastery, I’ll ask you to do
|
||||
something you’ve never done before. This illusion is akin to the <a href="http://www.toytent.com/Posters/985.html">floating lady</a>
|
||||
illusion that has been passed down through generations of magicians.</p>
|
||||
|
||||
|
||||
<p>Exit your console session.</p>
|
||||
|
||||
|
||||
<span class="caps">DELETE</span> your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
|
||||
<code>app/models</code> folder. (You can always get them back via the model generator… be fearless!)
|
||||
|
||||
<pre>rm app/models/*.rb</pre>
|
||||
|
||||
<p>Re-launch your console.</p>
|
||||
|
||||
|
||||
<p><strong>drums are still rolling…</strong></p>
|
||||
|
||||
|
||||
<p>Be prepared to applaud loudly…</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="punct">>></span> <span class="constant">Person</span>
|
||||
<span class="punct">=></span> <span class="constant">Person</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<p>You applaud loudly, but watch for more…</p>
|
||||
|
||||
|
||||
<p><pre class="syntax">
|
||||
<span class="punct">>></span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">new</span><span class="punct">.</span><span class="ident">valid?</span>
|
||||
<span class="punct">=></span> <span class="constant">false</span>
|
||||
<span class="punct">>></span> <span class="ident">person</span> <span class="punct">=</span> <span class="constant">Person</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="number">1</span><span class="punct">)</span>
|
||||
<span class="punct">=></span> <span class="punct"><</span><span class="constant">Person</span><span class="punct">:</span><span class="number">0x3958930</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">lastname</span><span class="punct">"=>"</span><span class="string">Williams</span><span class="punct">",</span> <span class="punct">"</span><span class="string">firstname</span><span class="punct">"=>"</span><span class="string">Nic</span><span class="punct">",</span>
|
||||
<span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">email</span><span class="punct">"=>"</span><span class="string">drnicwilliams@gmail.com</span><span class="punct">"}></span>
|
||||
<span class="punct">>></span> <span class="ident">person</span><span class="punct">.</span><span class="ident">valid?</span>
|
||||
<span class="punct">=></span> <span class="constant">true</span>
|
||||
<span class="punct">>></span> <span class="ident">person</span><span class="punct">.</span><span class="ident">memberships</span>
|
||||
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x393a000</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">group_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">person_id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">"}>]</span>
|
||||
<span class="punct">>></span> <span class="ident">person</span><span class="punct">.</span><span class="ident">groups</span>
|
||||
<span class="punct">=></span> <span class="punct">[<</span><span class="constant">Group</span><span class="punct">:</span><span class="number">0x390df60</span> <span class="attribute">@attributes</span><span class="punct">={"</span><span class="string">name</span><span class="punct">"=>"</span><span class="string">Magic Models Forum</span><span class="punct">",</span> <span class="punct">"</span><span class="string">id</span><span class="punct">"=>"</span><span class="string">1</span><span class="punct">",</span> <span class="punct">"</span><span class="string">description</span><span class="punct">"=></span><span class="constant">nil</span><span class="punct">}>]</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<h3>Tada!</h3>
|
||||
|
||||
|
||||
<p>The end.</p>
|
||||
|
||||
|
||||
<h3>Use modules to scope your magic</h3>
|
||||
|
||||
|
||||
<p>Only want to pick up tables starting with <code>blog_</code>?</p>
|
||||
|
||||
|
||||
<p><pre class="syntax"><span class="keyword">module </span><span class="module">Blog</span>
|
||||
<span class="ident">magic_module</span> <span class="symbol">:table_name_prefix</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">blog_</span><span class="punct">'</span>
|
||||
<span class="keyword">end</span>
|
||||
|
||||
<span class="constant">Blog</span><span class="punct">::</span><span class="constant">Post</span><span class="punct">.</span><span class="ident">table_name</span> <span class="comment"># => 'blog_posts'</span>
|
||||
</pre></p>
|
||||
|
||||
|
||||
<h2>Dr Nic’s Blog</h2>
|
||||
|
||||
|
||||
<p><a href="http://www.drnicwilliams.com">http://www.drnicwilliams.com</a> – for future announcements and
|
||||
other stories and things.</p>
|
||||
|
||||
|
||||
<h2>Articles about Magic Models</h2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><a href="http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/">Announcement</a></li>
|
||||
<li><a href="http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/"><span class="caps">BTS</span> – Class creation</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Forum</h2>
|
||||
|
||||
|
||||
<p><a href="http://groups.google.com/group/magicmodels">http://groups.google.com/group/magicmodels</a></p>
|
||||
|
||||
|
||||
<h2>Licence</h2>
|
||||
|
||||
|
||||
<p>This code is free to use under the terms of the <span class="caps">MIT</span> licence.</p>
|
||||
|
||||
|
||||
<h2>Contact</h2>
|
||||
|
||||
|
||||
<p>Comments are welcome. Send an email to <a href="mailto:drnicwilliams@gmail.com">Dr Nic Williams</a>
|
||||
or via his blog at <a href="http://www.drnicwilliams.com">http://www.drnicwilliams.com</a></p>
|
||||
<p class="coda">
|
||||
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 30th April 2007<br>
|
||||
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
||||
</p>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-567811-3";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
291
vendor/gems/dr_nic_magic_models-0.9.2/website/index.txt
vendored
Normal file
291
vendor/gems/dr_nic_magic_models-0.9.2/website/index.txt
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
h1. Dr Nic's Magic Models
|
||||
|
||||
If you've used Ruby on Rails you'll have written at least one model class like this:
|
||||
|
||||
<pre syntax='ruby'>
|
||||
class Person < ActiveRecord::Base
|
||||
has_many :memberships
|
||||
has_many :groups, :through => :memberships
|
||||
belongs_to :family
|
||||
validates_presence_of :firstname, :lastname, :email
|
||||
end
|
||||
</pre>
|
||||
|
||||
A few minutes later you'll have wondered to yourself,
|
||||
|
||||
<blockquote>
|
||||
Why do I have write my own <code>has_many</code>, <code>belongs_to</code>, and <code>validates_presence_of</code>
|
||||
commands if all the data is in the database schema?
|
||||
</blockquote>
|
||||
|
||||
Now, for the very first time, your classes can look like this:
|
||||
|
||||
<pre syntax='ruby'>
|
||||
class Person < ActiveRecord::Base
|
||||
end
|
||||
</pre>
|
||||
|
||||
or, if you are lazy...
|
||||
|
||||
<pre syntax='ruby'>
|
||||
class Person < ActiveRecord::Base; end
|
||||
</pre>
|
||||
|
||||
or, if you read right to the end of this page, this...
|
||||
|
||||
<pre syntax='ruby'>
|
||||
# Go fish.
|
||||
</pre>
|
||||
|
||||
Magic and mystery abound. All for you. Impress your friends, amaze your mother.
|
||||
|
||||
NOTE: The gratuitous use of *Dr Nic's* in the name should only enhance the mystical magikery,
|
||||
for magic needs a magician; and I love magic. I always wanted to create my own magic trick.
|
||||
So I shall be the magician for the sake of magic itself. I look a bit like Harry Potter too,
|
||||
if Harry were 32 and better dressed.
|
||||
|
||||
h2. Installation
|
||||
|
||||
To install the Dr Nic's Magic Models gem you can run the following command to
|
||||
fetch the gem remotely from RubyForge:
|
||||
<pre>
|
||||
gem install dr_nic_magic_models
|
||||
</pre>
|
||||
|
||||
or "download the gem manually":http://rubyforge.org/projects/magicmodels and
|
||||
run the above command in the download directory.
|
||||
|
||||
Now you need to <code>require</code> the gem into your Ruby/Rails app. Insert the following
|
||||
line into your script (use <code>config/environment.rb</code> for your Rails apps):
|
||||
|
||||
<pre>
|
||||
require 'dr_nic_magic_models'
|
||||
</pre>
|
||||
|
||||
Your application is now blessed with magical mystery.
|
||||
|
||||
h2. David Copperfield eat your Ruby-crusted heart out
|
||||
|
||||
Let's demonstrate the magical mystery in all its full-stage glory. Create a Ruby on Rails app (example uses sqlite3, but use your favourite databas):
|
||||
|
||||
<pre syntax="ruby">
|
||||
rails magic_show -d sqlite3
|
||||
cd magic_show
|
||||
ruby script/generate model Person
|
||||
ruby script/generate model Group
|
||||
ruby script/generate model Membership
|
||||
</pre>
|
||||
|
||||
Update the migration <code>001_create_people.rb</code> with:
|
||||
<pre syntax="ruby">
|
||||
class CreatePeople < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :people do |t|
|
||||
t.column :firstname, :string, :null => false
|
||||
t.column :lastname, :string, :null => false
|
||||
t.column :email, :string, :null => false
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :people
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
|
||||
Similarly, update the <code>def self.up</code> method of <code>002_create_groups.rb</code>
|
||||
with:
|
||||
<pre syntax="ruby">
|
||||
create_table :groups do |t|
|
||||
t.column :name, :string, :null => false
|
||||
t.column :description, :string
|
||||
end
|
||||
</pre>
|
||||
|
||||
and <code>003_create_memberships.rb</code> with:
|
||||
<pre syntax="ruby">
|
||||
create_table :memberships do |t|
|
||||
t.column :person_id, :integer, :null => false
|
||||
t.column :group_id, :integer, :null => false
|
||||
end
|
||||
</pre>
|
||||
|
||||
And run your migrations to create the three tables:
|
||||
<pre>
|
||||
rake db:migrate
|
||||
</pre>
|
||||
|
||||
h3. And now for some "woofle dust":http://en.wikipedia.org/wiki/List_of_conjuring_terms ...
|
||||
|
||||
At the end of <code>config/environment.rb</code> add the following line:
|
||||
|
||||
<pre>
|
||||
require 'dr_nic_magic_models'
|
||||
</pre>
|
||||
|
||||
Now, let's do a magic trick. First, let's check our model classes (<code>app/models/person.rb</code> etc):
|
||||
|
||||
<pre syntax="ruby">
|
||||
class Person < ActiveRecord::Base
|
||||
end
|
||||
class Group < ActiveRecord::Base
|
||||
end
|
||||
class Membership < ActiveRecord::Base
|
||||
end
|
||||
</pre>
|
||||
|
||||
Nothing suspicious here. We have no validations and no associations. Just some plain old model classes.
|
||||
|
||||
UPDATE: To turn on magic validations, you now need to invoke <code>generate_validations</code> on defined classes. So, update your model classes:
|
||||
|
||||
<pre syntax="ruby">
|
||||
class Person < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
class Group < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
class Membership < ActiveRecord::Base
|
||||
generate_validations
|
||||
end
|
||||
</pre>
|
||||
|
||||
For this trick, we'll need an ordinary console session. Any old one lying around the house will do.
|
||||
|
||||
<pre>
|
||||
ruby script/console
|
||||
</pre>
|
||||
|
||||
Now a normal model class is valid until you explicitly add <code>validates_xxx</code> commands.
|
||||
With Dr Nic's Magic Models:
|
||||
|
||||
<pre syntax="ruby">
|
||||
person = Person.new
|
||||
=> #<Person:0x393e0f8 @attributes={"lastname"=>"", "firstname"=>"", "email"=>""}, @new_record=true>
|
||||
person.valid?
|
||||
=> false
|
||||
person.errors
|
||||
=> #<ActiveRecord::Errors:0x3537b38 @errors={
|
||||
"firstname"=>["can't be blank", "is too long (maximum is 255 characters)"],
|
||||
"lastname"=>["can't be blank", "is too long (maximum is 255 characters)"],
|
||||
"email"=>["can't be blank", "is too long (maximum is 255 characters)"]},
|
||||
@base=#<Person:0x3538bf0 @errors=#<ActiveRecord::Errors:0x3537b38 ...>, @new_record=true,
|
||||
@attributes={"lastname"=>nil, "firstname"=>nil, "email"=>nil}>>
|
||||
</pre>
|
||||
|
||||
*Kapoow!* Instant validation! (NOTE: not as instant as it used to be - remember - you need to call <code>generate_validations</code> on each class as required)
|
||||
|
||||
Because you specified the three columns as <code>:null => false</code>,
|
||||
your ActiveRecord models will now automagically generated <code>validates_presence_of</code>
|
||||
for each non-null field, plus several other validations (since version 0.8.0).
|
||||
|
||||
Ok, we're just warming up.
|
||||
|
||||
Your models normally require association commands (<code>has_many</code>, <code>belongs_to</code>, etc, as
|
||||
demonstrated above) to have the brilliantly simple support that Rails/ActiveRecords are known for.
|
||||
|
||||
Let's just watch what Dr Nic's Magic Models can do without any effort at all...
|
||||
|
||||
<pre syntax="ruby">
|
||||
person = Person.create(:firstname => "Nic", :lastname => "Williams", :email => "drnicwilliams@gmail.com")
|
||||
group = Group.create(:name => "Magic Models Forum", :description => "http://groups.google.com/magicmodels")
|
||||
membership = Membership.create(:person => person, :group => group)
|
||||
person.memberships.length
|
||||
=> 1
|
||||
membership.person
|
||||
=> <Person:0x38898e8 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
||||
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
|
||||
group.memberships
|
||||
=> [<Membership:0x3c8cd70 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
|
||||
</pre>
|
||||
|
||||
|
||||
That final association trick is a ripper. Automatic generation of <code>has_many :through</code> associations...
|
||||
|
||||
<pre syntax="ruby">
|
||||
>> person.groups
|
||||
=> [<Group:0x39047e0 @attributes={"name"=>"Magic Models Forum", "id"=>"1", "description"=>nil}>]
|
||||
>> group.people
|
||||
=> [<Person:0x3c33580 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
||||
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>]
|
||||
</pre>
|
||||
|
||||
h3. Drum roll...
|
||||
|
||||
Ladies and gentlemen. For my final feat of magical mastery, I'll ask you to do
|
||||
something you've never done before. This illusion is akin to the "floating lady":http://www.toytent.com/Posters/985.html
|
||||
illusion that has been passed down through generations of magicians.
|
||||
|
||||
Exit your console session.
|
||||
|
||||
DELETE your three model classes: <code>person.rb, group.rb, and membership.rb</code> from the
|
||||
<code>app/models</code> folder. (You can always get them back via the model generator... be fearless!)
|
||||
|
||||
<pre>rm app/models/*.rb</pre>
|
||||
|
||||
Re-launch your console.
|
||||
|
||||
*drums are still rolling...*
|
||||
|
||||
Be prepared to applaud loudly...
|
||||
|
||||
<pre syntax="ruby">
|
||||
>> Person
|
||||
=> Person
|
||||
</pre>
|
||||
|
||||
You applaud loudly, but watch for more...
|
||||
|
||||
<pre syntax="ruby">
|
||||
>> Person.new.valid?
|
||||
=> false
|
||||
>> person = Person.find(1)
|
||||
=> <Person:0x3958930 @attributes={"lastname"=>"Williams", "firstname"=>"Nic",
|
||||
"id"=>"1", "email"=>"drnicwilliams@gmail.com"}>
|
||||
>> person.valid?
|
||||
=> true
|
||||
>> person.memberships
|
||||
=> [<Membership:0x393a000 @attributes={"group_id"=>"1", "id"=>"1", "person_id"=>"1"}>]
|
||||
>> person.groups
|
||||
=> [<Group:0x390df60 @attributes={"name"=>"Magic Models Forum", "id"=>"1", "description"=>nil}>]
|
||||
</pre>
|
||||
|
||||
h3. Tada!
|
||||
|
||||
The end.
|
||||
|
||||
h3. Use modules to scope your magic
|
||||
|
||||
Only want to pick up tables starting with <code>blog_</code>?
|
||||
|
||||
<pre syntax="ruby">module Blog
|
||||
magic_module :table_name_prefix => 'blog_'
|
||||
end
|
||||
|
||||
Blog::Post.table_name # => 'blog_posts'
|
||||
</pre>
|
||||
|
||||
h2. Dr Nic's Blog
|
||||
|
||||
"http://www.drnicwilliams.com":http://www.drnicwilliams.com - for future announcements and
|
||||
other stories and things.
|
||||
|
||||
h2. Articles about Magic Models
|
||||
|
||||
* "Announcement":http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/
|
||||
* "BTS - Class creation":http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/
|
||||
|
||||
|
||||
h2. Forum
|
||||
|
||||
"http://groups.google.com/group/magicmodels":http://groups.google.com/group/magicmodels
|
||||
|
||||
h2. Licence
|
||||
|
||||
This code is free to use under the terms of the MIT licence.
|
||||
|
||||
h2. Contact
|
||||
|
||||
Comments are welcome. Send an email to "Dr Nic Williams":mailto:drnicwilliams@gmail.com
|
||||
or via his blog at "http://www.drnicwilliams.com":http://www.drnicwilliams.com
|
||||
|
||||
285
vendor/gems/dr_nic_magic_models-0.9.2/website/javascripts/rounded_corners_lite.inc.js
vendored
Normal file
285
vendor/gems/dr_nic_magic_models-0.9.2/website/javascripts/rounded_corners_lite.inc.js
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* curvyCorners *
|
||||
* ------------ *
|
||||
* *
|
||||
* This script generates rounded corners for your divs. *
|
||||
* *
|
||||
* Version 1.2.9 *
|
||||
* Copyright (c) 2006 Cameron Cooke *
|
||||
* By: Cameron Cooke and Tim Hutchison. *
|
||||
* *
|
||||
* *
|
||||
* Website: http://www.curvycorners.net *
|
||||
* Email: info@totalinfinity.com *
|
||||
* Forum: http://www.curvycorners.net/forum/ *
|
||||
* *
|
||||
* *
|
||||
* This library is free software; you can redistribute *
|
||||
* it and/or modify it under the terms of the GNU *
|
||||
* Lesser General Public License as published by the *
|
||||
* Free Software Foundation; either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will *
|
||||
* be useful, but WITHOUT ANY WARRANTY; without even the *
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public *
|
||||
* License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser *
|
||||
* General Public License along with this library; *
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, *
|
||||
* MA 02111-1307 USA *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
|
||||
{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
|
||||
{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}
|
||||
else
|
||||
{ var startIndex = 1; var boxCol = arguments;}
|
||||
var curvyCornersCol = new Array(); if(arguments[0].validTags)
|
||||
var validElements = arguments[0].validTags; else
|
||||
var validElements = ["div"]; for(var i = startIndex, j = boxCol.length; i < j; i++)
|
||||
{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)
|
||||
{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}
|
||||
}
|
||||
this.objects = curvyCornersCol; this.applyCornersToAll = function()
|
||||
{ for(var x = 0, k = this.objects.length; x < k; x++)
|
||||
{ this.objects[x].applyCorners();}
|
||||
}
|
||||
}
|
||||
function curvyObject()
|
||||
{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, "height", "height"); var boxWidth = get_style(this.box, "width", "width"); var borderWidth = get_style(this.box, "borderTopWidth", "border-top-width"); var borderColour = get_style(this.box, "borderTopColor", "border-top-color"); var boxColour = get_style(this.box, "backgroundColor", "background-color"); var backgroundImage = get_style(this.box, "backgroundImage", "background-image"); var boxPosition = get_style(this.box, "position", "position"); var boxPadding = get_style(this.box, "paddingTop", "padding-top"); this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + "px" + " solid " + this.borderColour; this.backgroundImage = ((backgroundImage != "none")? backgroundImage : ""); this.boxContent = this.box.innerHTML; if(boxPosition != "absolute") this.box.style.position = "relative"; this.box.style.padding = "0px"; if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%"; if(this.settings.autoPad == true && this.boxPadding > 0)
|
||||
this.box.innerHTML = ""; this.applyCorners = function()
|
||||
{ for(var t = 0; t < 2; t++)
|
||||
{ switch(t)
|
||||
{ case 0:
|
||||
if(this.settings.tl || this.settings.tr)
|
||||
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + "px"; newMainContainer.style.top = 0 - topMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.topContainer = this.box.appendChild(newMainContainer);}
|
||||
break; case 1:
|
||||
if(this.settings.bl || this.settings.br)
|
||||
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + "px"; newMainContainer.style.bottom = 0 - botMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.bottomContainer = this.box.appendChild(newMainContainer);}
|
||||
break;}
|
||||
}
|
||||
if(this.topContainer) this.box.style.borderTopWidth = "0px"; if(this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for(var i in corners)
|
||||
{ if(i > -1 < 4)
|
||||
{ var cc = corners[i]; if(!this.settings[cc])
|
||||
{ if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
|
||||
{ var newCorner = document.createElement("DIV"); newCorner.style.position = "relative"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; if(this.backgroundImage == "")
|
||||
newCorner.style.backgroundColor = this.boxColour; else
|
||||
newCorner.style.backgroundImage = this.backgroundImage; switch(cc)
|
||||
{ case "tl":
|
||||
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + "px"; break; case "tr":
|
||||
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; newCorner.style.left = this.borderWidth + "px"; break; case "bl":
|
||||
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + "px"; newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break; case "br":
|
||||
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + "px"
|
||||
newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break;}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ if(this.masterCorners[this.settings[cc].radius])
|
||||
{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}
|
||||
else
|
||||
{ var newCorner = document.createElement("DIV"); newCorner.style.height = this.settings[cc].radius + "px"; newCorner.style.width = this.settings[cc].radius + "px"; newCorner.style.position = "absolute"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
|
||||
{ if((intx +1) >= borderRadius)
|
||||
var y1 = -1; else
|
||||
var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)
|
||||
{ if((intx) >= borderRadius)
|
||||
var y2 = -1; else
|
||||
var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)
|
||||
var y3 = -1; else
|
||||
var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}
|
||||
if((intx) >= j)
|
||||
var y4 = -1; else
|
||||
var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)
|
||||
{ for(var inty = (y1 + 1); inty < y2; inty++)
|
||||
{ if(this.settings.antiAlias)
|
||||
{ if(this.backgroundImage != "")
|
||||
{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)
|
||||
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}
|
||||
else
|
||||
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}
|
||||
}
|
||||
else
|
||||
{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}
|
||||
}
|
||||
}
|
||||
if(this.settings.antiAlias)
|
||||
{ if(y3 >= y2)
|
||||
{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}
|
||||
}
|
||||
else
|
||||
{ if(y3 >= y1)
|
||||
{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}
|
||||
}
|
||||
var outsideColour = this.borderColour;}
|
||||
else
|
||||
{ var outsideColour = this.boxColour; var y3 = y1;}
|
||||
if(this.settings.antiAlias)
|
||||
{ for(var inty = (y3 + 1); inty < y4; inty++)
|
||||
{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}
|
||||
}
|
||||
}
|
||||
this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}
|
||||
if(cc != "br")
|
||||
{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
|
||||
{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px"))); if(cc == "tl" || cc == "bl"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px";}
|
||||
if(cc == "tr" || cc == "tl"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px";}
|
||||
switch(cc)
|
||||
{ case "tr":
|
||||
pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "tl":
|
||||
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "bl":
|
||||
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px"; break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(newCorner)
|
||||
{ switch(cc)
|
||||
{ case "tl":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "tr":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "bl":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case "br":
|
||||
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
|
||||
radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)
|
||||
{ if(z == "t" || z == "b")
|
||||
{ if(radiusDiff[z])
|
||||
{ var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r"); var newFiller = document.createElement("DIV"); newFiller.style.height = radiusDiff[z] + "px"; newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
|
||||
newFiller.style.position = "absolute"; newFiller.style.fontSize = "1px"; newFiller.style.overflow = "hidden"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)
|
||||
{ case "tl":
|
||||
newFiller.style.bottom = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case "tr":
|
||||
newFiller.style.bottom = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case "bl":
|
||||
newFiller.style.top = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case "br":
|
||||
newFiller.style.top = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}
|
||||
}
|
||||
var newFillerBar = document.createElement("DIV"); newFillerBar.style.position = "relative"; newFillerBar.style.fontSize = "1px"; newFillerBar.style.overflow = "hidden"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)
|
||||
{ case "t":
|
||||
if(this.topContainer)
|
||||
{ if(this.settings.tl.radius && this.settings.tr.radius)
|
||||
{ newFillerBar.style.height = topMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != "")
|
||||
newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; this.topContainer.appendChild(newFillerBar);}
|
||||
this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";}
|
||||
break; case "b":
|
||||
if(this.bottomContainer)
|
||||
{ if(this.settings.bl.radius && this.settings.br.radius)
|
||||
{ newFillerBar.style.height = botMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != "")
|
||||
newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px"; this.bottomContainer.appendChild(newFillerBar);}
|
||||
}
|
||||
break;}
|
||||
}
|
||||
}
|
||||
if(this.settings.autoPad == true && this.boxPadding > 0)
|
||||
{ var contentContainer = document.createElement("DIV"); contentContainer.style.position = "relative"; contentContainer.innerHTML = this.boxContent; contentContainer.className = "autoPadDiv"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)
|
||||
contentContainer.style.paddingTop = topPadding + "px"; if(botMaxRadius < this.boxPadding)
|
||||
contentContainer.style.paddingBottom = botMaxRadius + "px"; contentContainer.style.paddingLeft = this.boxPadding + "px"; contentContainer.style.paddingRight = this.boxPadding + "px"; this.contentDIV = this.box.appendChild(contentContainer);}
|
||||
}
|
||||
this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)
|
||||
{ var pixel = document.createElement("DIV"); pixel.style.height = height + "px"; pixel.style.width = "1px"; pixel.style.position = "absolute"; pixel.style.fontSize = "1px"; pixel.style.overflow = "hidden"; var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius); if(image == -1 && this.backgroundImage != "")
|
||||
{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";}
|
||||
else
|
||||
{ pixel.style.backgroundColor = colour;}
|
||||
if (transAmount != 100)
|
||||
setOpacity(pixel, transAmount); pixel.style.top = inty + "px"; pixel.style.left = intx + "px"; newCorner.appendChild(pixel);}
|
||||
}
|
||||
function insertAfter(parent, node, referenceNode)
|
||||
{ parent.insertBefore(node, referenceNode.nextSibling);}
|
||||
function BlendColour(Col1, Col2, Col1Fraction)
|
||||
{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}
|
||||
function IntToHex(strNum)
|
||||
{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}
|
||||
function MakeHex(x)
|
||||
{ if((x >= 0) && (x <= 9))
|
||||
{ return x;}
|
||||
else
|
||||
{ switch(x)
|
||||
{ case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F";}
|
||||
}
|
||||
}
|
||||
function pixelFraction(x, y, r)
|
||||
{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))
|
||||
{ whatsides = "Left"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))
|
||||
{ whatsides = whatsides + "Top"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))
|
||||
{ whatsides = whatsides + "Right"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}
|
||||
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))
|
||||
{ whatsides = whatsides + "Bottom"; xvalues[point] = intersect - x; yvalues[point] = 0;}
|
||||
switch (whatsides)
|
||||
{ case "LeftRight":
|
||||
pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case "TopRight":
|
||||
pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case "TopBottom":
|
||||
pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case "LeftBottom":
|
||||
pixelfraction = (yvalues[0]*xvalues[1])/2; break; default:
|
||||
pixelfraction = 1;}
|
||||
return pixelfraction;}
|
||||
function rgb2Hex(rgbColour)
|
||||
{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}
|
||||
catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");}
|
||||
return hexColour;}
|
||||
function rgb2Array(rgbColour)
|
||||
{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")")); var rgbArray = rgbValues.split(", "); return rgbArray;}
|
||||
function setOpacity(obj, opacity)
|
||||
{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != "IFRAME")
|
||||
{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";}
|
||||
else if(typeof(obj.style.opacity) != "undefined")
|
||||
{ obj.style.opacity = opacity/100;}
|
||||
else if(typeof(obj.style.MozOpacity) != "undefined")
|
||||
{ obj.style.MozOpacity = opacity/100;}
|
||||
else if(typeof(obj.style.filter) != "undefined")
|
||||
{ obj.style.filter = "alpha(opacity:" + opacity + ")";}
|
||||
else if(typeof(obj.style.KHTMLOpacity) != "undefined")
|
||||
{ obj.style.KHTMLOpacity = opacity/100;}
|
||||
}
|
||||
function inArray(array, value)
|
||||
{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}
|
||||
return false;}
|
||||
function inArrayKey(array, value)
|
||||
{ for(key in array){ if(key === value) return true;}
|
||||
return false;}
|
||||
function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}
|
||||
else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}
|
||||
else { elm['on' + evType] = fn;}
|
||||
}
|
||||
function removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent("on"+evType, fn); return r;} else { alert("Handler could not be removed");}
|
||||
}
|
||||
function format_colour(colour)
|
||||
{ var returnColour = "#ffffff"; if(colour != "" && colour != "transparent")
|
||||
{ if(colour.substr(0, 3) == "rgb")
|
||||
{ returnColour = rgb2Hex(colour);}
|
||||
else if(colour.length == 4)
|
||||
{ returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}
|
||||
else
|
||||
{ returnColour = colour;}
|
||||
}
|
||||
return returnColour;}
|
||||
function get_style(obj, property, propertyNS)
|
||||
{ try
|
||||
{ if(obj.currentStyle)
|
||||
{ var returnVal = eval("obj.currentStyle." + property);}
|
||||
else
|
||||
{ if(isSafari && obj.style.display == "none")
|
||||
{ obj.style.display = ""; var wasHidden = true;}
|
||||
var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)
|
||||
{ obj.style.display = "none";}
|
||||
}
|
||||
}
|
||||
catch(e)
|
||||
{ }
|
||||
return returnVal;}
|
||||
function getElementsByClass(searchClass, node, tag)
|
||||
{ var classElements = new Array(); if(node == null)
|
||||
node = document; if(tag == null)
|
||||
tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)"); for (i = 0, j = 0; i < elsLen; i++)
|
||||
{ if(pattern.test(els[i].className))
|
||||
{ classElements[j] = els[i]; j++;}
|
||||
}
|
||||
return classElements;}
|
||||
function newCurvyError(errorMessage)
|
||||
{ return new Error("curvyCorners Error:\n" + errorMessage)
|
||||
}
|
||||
96
vendor/gems/dr_nic_magic_models-0.9.2/website/stylesheets/screen.css
vendored
Normal file
96
vendor/gems/dr_nic_magic_models-0.9.2/website/stylesheets/screen.css
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
body {
|
||||
background-color: #115;
|
||||
font-family: "Georgia", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6em;
|
||||
padding: 1.6em 0 0 0;
|
||||
color: #eee;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #77f;
|
||||
}
|
||||
h1 {
|
||||
font-family: sans-serif;
|
||||
font-weight: normal;
|
||||
font-size: 4em;
|
||||
line-height: 0.8em;
|
||||
letter-spacing: -0.1ex;
|
||||
}
|
||||
li {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: square;
|
||||
}
|
||||
a {
|
||||
color: #99f;
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
}
|
||||
blockquote {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
border-left: 1px solid #eee;
|
||||
padding-left: 1em;
|
||||
}
|
||||
.caps {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
#main {
|
||||
width: 55em;
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.coda {
|
||||
text-align: right;
|
||||
color: #77f;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: monospace;
|
||||
font-size: 90%;
|
||||
line-height: 1.4em;
|
||||
color: #ff8;
|
||||
background-color: #111;
|
||||
padding: 2px 10px 2px 10px;
|
||||
}
|
||||
.comment { color: #aaa; font-style: italic; }
|
||||
.keyword { color: #eff; font-weight: bold; }
|
||||
.punct { color: #eee; font-weight: bold; }
|
||||
.symbol { color: #0bb; }
|
||||
.string { color: #6b4; }
|
||||
.ident { color: #ff8; }
|
||||
.constant { color: #66f; }
|
||||
.regex { color: #ec6; }
|
||||
.number { color: #F99; }
|
||||
.expr { color: #227; }
|
||||
|
||||
#version {
|
||||
float: right;
|
||||
text-align: right;
|
||||
font-family: sans-serif;
|
||||
font-weight: normal;
|
||||
background-color: #ff8;
|
||||
color: #66f;
|
||||
padding: 15px 20px 10px 20px;
|
||||
margin: 0 auto;
|
||||
border: 3px solid #66f;
|
||||
}
|
||||
|
||||
#version .numbers {
|
||||
display: block;
|
||||
font-size: 4em;
|
||||
line-height: 0.8em;
|
||||
letter-spacing: -0.1ex;
|
||||
}
|
||||
|
||||
#version a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
3
vendor/gems/dr_nic_magic_models-0.9.2/website/template.js
vendored
Normal file
3
vendor/gems/dr_nic_magic_models-0.9.2/website/template.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// <%= title %>
|
||||
var version = <%= version.to_json %>;
|
||||
<%= body %>
|
||||
55
vendor/gems/dr_nic_magic_models-0.9.2/website/template.rhtml
vendored
Normal file
55
vendor/gems/dr_nic_magic_models-0.9.2/website/template.rhtml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>
|
||||
<%= title %>
|
||||
</title>
|
||||
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<script type="text/javascript" src="version-raw.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
settings = {
|
||||
tl: { radius: 10 },
|
||||
tr: { radius: 10 },
|
||||
bl: { radius: 10 },
|
||||
br: { radius: 10 },
|
||||
antiAlias: true,
|
||||
autoPad: true,
|
||||
validTags: ["div"]
|
||||
}
|
||||
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
||||
versionBox.applyCornersToAll();
|
||||
|
||||
document.getElementById("version_num").innerHTML = version;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<p><a href="/">↩ More Magic</a></p>
|
||||
|
||||
<div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
|
||||
Get Version
|
||||
<a id="version_num" href="<%= download %>" class="numbers"></a>
|
||||
</div>
|
||||
<h1><%= title %></h1>
|
||||
<%= body %>
|
||||
<p class="coda">
|
||||
<a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, <%= modified.pretty %><br>
|
||||
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
||||
</p>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-567811-3";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
vendor/gems/dr_nic_magic_models-0.9.2/website/version-raw.js
vendored
Normal file
3
vendor/gems/dr_nic_magic_models-0.9.2/website/version-raw.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// Version JS file
|
||||
var version = "0.9.2";
|
||||
MagicAnnouncement.show('magicmodels', version);
|
||||
2
vendor/gems/dr_nic_magic_models-0.9.2/website/version-raw.txt
vendored
Normal file
2
vendor/gems/dr_nic_magic_models-0.9.2/website/version-raw.txt
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
h1. Version JS file
|
||||
MagicAnnouncement.show('magicmodels', version);
|
||||
4
vendor/gems/dr_nic_magic_models-0.9.2/website/version.js
vendored
Normal file
4
vendor/gems/dr_nic_magic_models-0.9.2/website/version.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
// Version JS file
|
||||
var version = "0.9.2";
|
||||
|
||||
document.write(" - " + version);
|
||||
3
vendor/gems/dr_nic_magic_models-0.9.2/website/version.txt
vendored
Normal file
3
vendor/gems/dr_nic_magic_models-0.9.2/website/version.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
h1. Version JS file
|
||||
|
||||
document.write(" - " + version);
|
||||
Reference in New Issue
Block a user