Rails plugins / Plugin tools

From WhyNotWiki

Jump to: navigation, search

Contents

[edit] Plugins for creating plugins / plugin tools/extensions / more powerful plugins

[edit] Alternative to Engines: plugin_dependencies, loaded_plugins, plugin_migrations, plugin_assets, appable_plugins, and plugin_routing

http://www.pluginaweek.org/2006/12/14/rails-engines-vs-6-plugins/

Our plugins aren’t meant to altogether replace Engines. They are a means of appealing to those who don’t like Engines so that we can all continue to develop plugins that add migrations, models, controllers, helpers, etc. and everyone can use them, engine-lovers and engine-haters alike.

If you’ve come so far as to like each of our 6 plugins and use them all together, then this boils down to close to the same functionality that Engines offers.

You can either install them individually or all at once using the "Plugins plus" plugin bundle.

[edit] star_full.gif star_full.gif star_full.gif Plugins plus

Homepage: http://wiki.pluginaweek.org/Plugins_plus [1]
Source code: gem install plugins_plus or http://svn.pluginaweek.org/trunk/plugins/rails/plugins_plus








I've been using most of the plugins contained in plugins_plus individually for a while now, so I was excited to see a single plugin that would save me from installing each one individually!

Installation:

gem install plugins_plus

config/environment.rb
  require 'plugins_plus'
  ...
  Rails::Initializer.run do |config|
  ...

[edit] Problem: Can't load as gem

[link to mailing list...]

First I tried the gem version, because gems seem the most convenient to me...

I started a brand-new Rails application so that there could be no other variables.

 > ./script/about
About your application's environment
Ruby version                 1.8.5 (i386-linux)
RubyGems version             0.9.2
Rails version                1.2.3
Active Record version        1.15.3
Action Pack version          1.13.3
Action Web Service version   1.2.3
Action Mailer version        1.3.3
Active Support version       1.4.2
Application root             /home/tyler/code/applications/t
Environment                  development
Database adapter             mysql

> gem list plugins_plus
plugins_plus (0.1.0)

Following the simple instructions at http://svn.pluginaweek.org/trunk/plugins/rails/plugins_plus/README , I added this near the top of my environment.rb:

  require 'plugins_plus'

This is what I got when I did ./script/server:

NameError: undefined method `initialize_schema_information' for module `ActiveRecord::ConnectionAdapters::SchemaStatements'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/module/aliasing.rb:28:in `alias_method'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/module/aliasing.rb:28:in `alias_method_chain'
/usr/lib/ruby/gems/1.8/gems/plugin_migrations-0.1.0/lib/plugin_migrations/extensions/schema_statements.rb:13
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/plugin_migrations-0.1.0/lib/plugin_migrations.rb:3
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/plugins_plus-0.1.0/lib/plugins_plus.rb:2
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:33:in `gem_original_require'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:33:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/home/tyler/code/applications/t/config/environment.rb:13

As you know, initialize_schema_information is defined in: /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/schema_statements.rb:235

So it looks like somehow it ended up trying to load the plugin before active_record/connection_adapters/abstract/schema_statements.rb ever got called, which is kind of curious...

Sure enough, I threw some debug output in /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/schema_statements.rb and tried starting the server but DIDN'T SEE the debug output.

Suspecting that perhaps the reason it wasn't loading active_record/connection_adapters/abstract/schema_statements.rb was because I didn't have any models that _used_ AR in my app, I tried to generate a model... but got a DIFFERENT error:

> ./script/generate model whatever
/usr/lib/ruby/gems/1.8/gems/loaded_plugins-0.1.0/lib/loaded_plugins/loaded_plugins.rb:4: undefined method `mattr_accessor' for PluginAWeek::LoadedPlugins:Module (NoMethodError)
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from /usr/lib/ruby/gems/1.8/gems/loaded_plugins-0.1.0/lib/loaded_plugins.rb:3
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from /usr/lib/ruby/gems/1.8/gems/plugins_plus-0.1.0/lib/plugins_plus.rb:1
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:33:in `gem_original_require'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:33:in `require'
        from ./script/../config/../config/environment.rb:13
  • Stopped requiring 'plugins_plus'
  • ./script/generate model whatever
  • rake db:migrate
  • * I DID see the output from active_record/connection_adapters/abstract/schema_statements.rb during the migrate
  • ./script/server
  • * Did NOT see any output from active_record/connection_adapters/abstract/schema_statements.rb
  • requiring 'plugins_plus' again
  • ./script/server
  • * Did NOT see any output from active_record/connection_adapters/abstract/schema_statements.rb
  • * Still got same undefined method `initialize_schema_information' error.

Any suggestions?


[edit] Caveat: Must install using the ./script/plugin install -x option=

[link to mailing list...]

Next I tried installing it as a non-gem plugin:

./script/plugin install http://svn.pluginaweek.org/trunk/plugins/rails/plugins_plus
+ ./plugins_plus/CHANGELOG
+ ./plugins_plus/MIT-LICENSE
+ ./plugins_plus/README
+ ./plugins_plus/Rakefile
+ ./plugins_plus/init.rb
+ ./plugins_plus/lib/plugins_plus.rb
+ ./plugins_plus/tasks/plugins_plus_tasks.rake

Weird! Why aren't there more files in lib??

Looking at http://dev.pluginaweek.org/browser/trunk/plugins/rails/plugins_plus/lib , I see the reason:

Property svn:externals set to
appable_plugins http://svn.pluginaweek.org/trunk/plugins/rails/appable_plugins
loaded_plugins http://svn.pluginaweek.org/trunk/plugins/rails/loaded_plugins
partial_plugin_list http://svn.pluginaweek.org/trunk/plugins/rails/partial_plugin_list
plugin_assets http://svn.pluginaweek.org/trunk/plugins/action_pack/plugin_assets
plugin_dependencies http://svn.pluginaweek.org/trunk/plugins/rails/plugin_dependencies
plugin_migrations http://svn.pluginaweek.org/trunk/plugins/active_record/migrations/plugin_migrations
plugin_routing http://svn.pluginaweek.org/trunk/plugins/action_pack/plugin_routing

My app isn't _in_ a repository because it's just a throwaway app for test purposes.

I suggest putting a note in your readme that your application MUST be in a Subversion repository and you MUST install it using the -x option if you want the dependee plugins to be installed automatically!

Further evidence that this plugin will only work if those externals are in place: script/../config/../vendor/plugins/plugins_plus/init.rb:

base_path = File.dirname(__FILE__)
configuration.plugin_paths << "#{base_path}/lib"
load_plugin "#{base_path}/lib/partial_plugin_list"
load_plugin "#{base_path}/lib/loaded_plugins"
load_plugin "#{base_path}/lib/plugin_migrations"
load_plugin "#{base_path}/lib/plugin_assets"
load_plugin "#{base_path}/lib/appable_plugins"
load_plugin "#{base_path}/lib/plugin_routing"
load_plugin "#{base_path}/lib/plugin_dependencies"
~/code/applications/t > svn add ../t
> ./script/plugin remove plugins_plus
> ./script/plugin install -x http://svn.pluginaweek.org/trunk/plugins/rails/plugins_plus
...
Fetching external item into '/home/tyler/code/applications/t/vendor/plugins/plugins_plus/lib/appable_plugins'
...

> ./script/server
...

Seems to work!

Incidentally, I'm still NOT seeing any output from active_record/connection_adapters/abstract/schema_statements.rb , but that doesn't seem to matter. SOMEHOW initialize_schema_information is getting defined, as this test verifies...

./vendor/plugins/plugins_plus/lib/plugin_migrations/lib/plugin_migrations/extensions/schema_statements.rb

      require 'pp'
      pp ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods.grep(/initialize_schema_information/)
      alias_method_chain :initialize_schema_information, :plugins

=> ["initialize_schema_information", "initialize_schema_information_with_plugins"]

The plugin install worked both with this line and without:

  config.plugins = [
    'plugins_plus',
    '*'


[edit] star_full.gif star_full.gif star_full.gif Appable plugins

Homepage: http://wiki.pluginaweek.org/Appable_plugins
Documentation: Readme
Source code: http://svn.pluginaweek.org/trunk/plugins/rails/appable_plugins
Project/Development: http://dev.pluginaweek.org/browser/trunk/plugins/rails/appable_plugins


Description: appable_plugins adds the ability for plugins to share models, controllers, and helpers with your Rails application. Classes are automatically mixed in with your own models/controllers/helpers.
Depends on: [[:Plugins:
  • loaded_plugins
  • plugin_dependencies|Plugins:
  • loaded_plugins
  • plugin_dependencies]]





[edit] Installation

    ./script/plugin install -x http://svn.pluginaweek.org/trunk/plugins/rails/loaded_plugins/
  ./script/plugin install -x http://svn.pluginaweek.org/trunk/plugins/rails/plugin_dependencies
./script/plugin install -x http://svn.pluginaweek.org/trunk/plugins/rails/appable_plugins

(The indentation is an attempt at making it look like an upside-down dependency tree.)

You need to make sure plugin_dependencies is loaded first.

[edit] Examples

http://wiki.pluginaweek.org/Appable_plugins. Retrieved on 2007-04-20 10:51.

acts_as_commentable/
acts_as_commentable/app/
acts_as_commentable/app/models/
acts_as_commentable/app/models/comment.rb
acts_as_commentable/lib/
acts_as_commentable/lib/acts_as_commentable.rb
acts_as_commentable/init.rb

If you, as a user of this plugin, want to then add additional methods or even override methods from the acts_as_commentable plugin, you would simply create a file named comment.rb as you normally would in your application's app/models/ folder. For example,

my_app/
my_app/app/
my_app/app/models/
my_app/app/models/comment.rb

[...]

The order in which multiple models/controllers/helpers are loaded is based on the order in which the plugins were loaded. So in this example, since there was only 1 plugin, the Comment model in acts_as_commentable will be loaded first and then your application's Comment model.

[edit] star_full.gif star_full.gif star_empty.gif Plugin assets

Homepage: http://wiki.pluginaweek.org/Plugin_assets
Documentation: Readme
Source code: http://svn.pluginaweek.org/trunk/plugins/action_pack/plugin_assets
Project/Development: http://dev.pluginaweek.org/browser/trunk/plugins/action_pack/plugin_assets


Description: adds the ability to automate the copying of plugin assets into your application's public/ folder, in addition to providing tasks for semi-automatically performing updates.
Depends on: [[:Plugins:
  • loaded_plugins|Plugins:
  • loaded_plugins]]





[edit] Installation

  ./script/plugin install -x http://svn.pluginaweek.org/trunk/plugins/rails/loaded_plugins/
./script/plugin install -x http://svn.pluginaweek.org/trunk/plugins/action_pack/plugin_assets

(The indentation is an attempt at making it look like an upside-down dependency tree.)

[edit] Usage

rake assets:list
rake assets:update -- skips those that already exist
rake assets:copy   -- overwrites if already exist


[edit] star_full.gif star_empty.gif star_empty.gif Loaded plugins

Homepage: http://wiki.pluginaweek.org/Loaded_plugins
Source code: http://svn.pluginaweek.org/trunk/plugins/rails/loaded_plugins/


As listed in other directories: http://rubyfurnace.com/plugins/loaded_plugins , http://www.agilewebdevelopment.com/plugins/betternestedset






http://wiki.pluginaweek.org/Loaded_plugins

loaded_plugins adds a global variable $LOADED_PLUGINS to the Rails environment that lists the paths to the base directory of each plugin that was loaded during initialization. The paths are listed in the order in which they were loaded. Once initialization is complete, $LOADED_PLUGINS is frozen to prevent it from accidentally being overwritten.

[edit] star_full.gif star_full.gif star_full.gif Plugin dependencies

Homepage: http://wiki.pluginaweek.org/Plugin_dependencies
Source code: http://svn.pluginaweek.org/trunk/plugins/rails/plugin_dependencies/
Project/Development: http://dev.pluginaweek.org/browser/trunk/plugins/rails/plugin_dependencies







[edit] Motivation

http://svn.pluginaweek.org/trunk/plugins/rails/plugin_dependencies/README (modified)

The current convention within Rails is to load plugins in alphabetical order. This poses a problem when certain plugins must be loaded before others.

For example, suppose you write a plugin called acts_as_addressable that uses the acts_as_enumerated plugin by Trevor Squires at http://svn.protocool.com/rails/plugins/enumerations_mixin/. You would then have a directory structure like the following:

  vendor/
  vendor/plugins
  vendor/plugins/acts_as_addressable
  vendor/plugins/acts_as_enumerated

Ordered alphabetically, acts_as_addressable will be loaded BEFORE acts_as_enumerated. This could potentially cause issues if you were assuming in your plugin that acts_as_enumerated had already been loaded.

...

This plugin addresses these issues by giving all plugins/gems the ability to define what other plugins they depend on using a similar API to that of RubyGems.

[edit] Usage

http://svn.pluginaweek.org/trunk/plugins/rails/plugin_dependencies/README

For example, the acts_as_addressable.rb would look like the following:

acts_as_addressable/lib/acts_as_addressable.rb:
  require_plugin 'acts_as_enumerated'
  ...

When Rails is initialized, even though acts_as_addressable.rb will be executed first, the require does two things:

  1. Ensure that the acts_as_enumerated plugin is present. If it's not, an exception will be thrown.
  2. Load the acts_as_enumerated plugin and then continue initialization of the acts_as_addressable plugin.

This gives plugin developers the ability to add descriptive information about dependencies directly within their plugins rather than forcing the load order based on the directory names.

[edit] Installation

Option 1: As a gem (Preferred by User:Tyler)

> sudo gem install plugin_dependencies

config/environment.rb:
require 'plugin_dependencies'
Rails::Initializer.run do |config|
  ...

(It seems allowable to have it installed as a plugin in addition to having it installed as a gem. This might be advantageous in order to ensure that ./vendor/plugins/plugin_dependencies/tasks/plugin_dependencies_tasks.rake is loaded. But I don't know what plugin_dependencies_tasks.rake is for, so I can't comment on whether that's necessary or not.)

Option 2: As a plugin

This plugin must be loaded before any plugins that use it:

  config.plugins = ['plugin_dependencies'] + Dir.new('vendor/plugins').entries.reject {|f| f =~ /^\./}

(See Rails plugins and libraries / Installing and using#Specifying_load_order for details.)

[edit] Problem: undefined method `mattr_accessor'

I'd been using the plugin_dependencies gem before without problems (I thought), and it seems like I'm still able to start the server when I have a require 'plugin_dependencies' in environment.rb . HOWEVER, I get these errors, respectively, when I try to run ./script/about and ./script/console, and I'm not sure why...

> ./script/about
/usr/lib/ruby/gems/1.8/gems/plugin_dependencies-0.1.0/lib/plugin_dependencies/plugin_dependencies.rb:3: undefined method `mattr_accessor' for PluginAWeek::PluginDependencies:Module (NoMethodError)
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from /usr/lib/ruby/gems/1.8/gems/plugin_dependencies-0.1.0/lib/plugin_dependencies.rb:1
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:33:in `gem_original_require'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:33:in `require'
        from ./script/../config/../config/environment.rb:14
> ./script/console
Loading development environment.
/usr/lib/ruby/gems/1.8/gems/plugin_dependencies-0.1.0/lib/plugin_dependencies/plugin_dependencies.rb:3:NoMethodError: undefined method `mattr_accessor' for PluginAWeek::PluginDependencies:Module
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/assertions/selector_assertions.rb:525:NoMethodError: undefined method `camelize' for "top":String
./script/../config/../config/../app/controllers/application.rb:4:NameError: uninitialized constant ActionController::Base
Welcome!
irb -> (Ctrl-D)Loaded suite irb
Started
Finished in 0.000663 seconds.
0 tests, 0 assertions, 0 failures, 0 errors

(Not sure why it's trying to run a test suite there?!)

Fortunately, I can just fall back to using the non-gem version with plugins_plus and everything works fine.



[edit] Plugems

Project/Development: http://rubyforge.org/projects/plugems/


Description: Rails framework for fully 'gemified' applications and shared dependencies. Dependency management, views, rake tasks, configuration files, etc. supported directly via Rubygems. Has proved critical for us for large-scale enterprise Rails development.




Readiness: (Probably has a gem though) This Project Has Not Released Any Files 2007-03-23 17:10, Registered: 2007-02-16 13:24



[edit] Plugin migrations

See Rails plugins and libraries / Database-level#Plugin migrations

[edit] [Engines (category)]: more powerful plugins

http://rails-engines.org/

Rails Engines are a way of dropping in whole chunks of functionality into your existing application without affecting any of your existing code. They could also be described as application aspects, or vertical application slices – top-to-bottom units which provide full MVC coverage for a certain, specific application function.

Engines can be as lightweight as the simplest plugin, or as full-featured as your your imagination can conceive. They are a natural successor to Rails' original Generator mechanism, or alternatively, plugins with all the power you could ever hope for.

http://rails-engines.org/faq/components-vs-plugins-vs-engines/:

Engines are also useful when you have an entire 'subsystem' of a Rails application (such as managing users & permissions) where you have model objects, controllers to manipulate/administer those objects (updating, creating new ones) and a full set of views & helpers to display information about those objects. Engines are like a slice of an application from top (views/helpers) to bottom (models) which can be dropped into an existing application and appear as if they always existed in the normal /app directory. Developers can selectively override parts of Engines as they need to handle their application (such as changing the user/home view to display a silly name), without affecting the rest of the Engine).

[edit] Engines: Better than generators

http://rails-engines.org/faq/engines-vs-generators/:

The engines plugin extends Rails' own minimal plugin system just enough to allow you to include in your plugin almost any type of file you might find in a regular Rails application: controllers, views, helpers, libraries, models, schemas, tests, stylesheets and javascripts... anything you can think of, essentially.
These files are contained within a single directory inside /vendor/plugins, completely isolating them from the rest of your application and therefore making it trivial to update to new versions.
It is still crucial that you as the developer be allowed to alter the behaviour of this packaged code to suit the individual needs of your application. With this in mind, the Engines plugin allows you to override the behaviour of engine code in a simple and clear way:
  • single views can be provided which are automatically used instead of those provided with the engine
  • controller actions can be overridden individually in your application, isolating your custom code from the underlying default implementation
  • model and library code is normally provided as a ruby Module, making it simple to include in your own custom Models
Developing an engine is a much more natural process, compared to creating generators - there is no 'ERb translation step', and changes to an engine can be made and committed in one application and then propagated to another application with no intermediate stages. Engine code looks exactly like normal Rails application code, making it intuitive to skim when you are examining an engine's behavior.










[edit] Information about creating/writing plugins

[edit] [Ruby-general] Problem: loading a file can have side-effects; make it possible to load the file without those side-effects; in other words, two-stage initialization

You'd want to be able to do something like this:

SomeModule::SomeClass::do_the_usual_initialization = false
require 'some_class'

But: You can't do that before SomeModule::SomeClass have been defined. And it won't be defined until we load the file which contains their definition! But we can't do that without getting the unwanted side-effects, which is why we were doing the SomeModule::SomeClass::do_the_usual_initialization = false in the first place, to prevent those side-effects.

Catch 22.

Solution: Create dummy modules/classes.

Easiest way to do that?

Class.new(:name => :SomeClass, :parent => :SomeModule)::do_the_usual_initialization = false
require 'some_class'

(see Ruby libraries / Core#Module creation helper)

Would that work?

I think it would.

[edit] acts_as plugins

Bruce Tate (2007-03-13). Crossing borders: Extensions in Rails: The anatomy of an acts_as plug-in (http://www-128.ibm.com/developerworks/java/library/j-cb03137/index.html). Retrieved on 2007-03-14 10:15.

module ActMacro
  # Configuration options are
  #
  # * +column+ - specifies the column name to use for keeping the state (default: state)
  # * +initial+ - specifies an initial state for newly created objects (required)
  def acts_as_state_machine(opts)
    self.extend(ClassMethods)
    raise NoInitialState unless opts[:initial]
    
    write_inheritable_attribute :states, {}
    write_inheritable_attribute :initial_state, opts[:initial]
    write_inheritable_attribute :transition_table, {}
    write_inheritable_attribute :event_table, {}
    write_inheritable_attribute :state_column, opts[:column] || 'state'
    
    class_inheritable_reader    :initial_state
    class_inheritable_reader    :state_column
    class_inheritable_reader    :transition_table
    class_inheritable_reader    :event_table
    
    self.send(:include, ScottBarron::Acts::StateMachine::InstanceMethods)

    before_create               :set_initial_state
    after_create                :run_initial_state_actions
  end
end

...

Go back to the [write_inheritable_attribute and class_inheritable_reader macros (category)]. You may be wondering why the module doesn't use simple inheritance. The reason is simple: The module has an inheritance hierarchy of its own. These macros allow the module to project these attributes onto the target class -- Nonprofit in this example. The most important attributes are state_column and a series of transition tables containing the states, events, and transitions. Now it's time to add the class methods that form the DSL.






[edit] Information about creating/writing plugins: Testing plugins

Rails plugins and libraries / Testing plugins edit

[edit] test_helper files / Test initialization

[edit] star_full.gif star_full.gif star_empty.gif Example from acts_as_ordered_tree

Notable features:

  • Depends on parent app's Rails "environment" (boot.rb) but provides own database and schema. (Bad: Means it can only be tested when installed as plugin within context of an app.)
  • Uses sqlite3 (in memory), so:
    • it doesn't affect the parent app's test database (so that doesn't have to be reloaded when the plugin test is finished),
    • the user of the plugin doesn't need to do any extra configuration to run tests,
    • and it doesn't even litter the filesystem with any database files!


./vendor/plugins/acts_as_ordered_tree/test/abstract_unit.rb

ENV["RAILS_ENV"] = "test"

require File.dirname(__FILE__) + '/../../../../config/boot'

require 'rubygems'
require 'test/unit'
# The only part of Rails that is actually needed, apparently
require 'active_record'

# Use a special database for this plugin tests. Output to a local log file.
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
ActiveRecord::Base.establish_connection(config['database'])

# Load the plugin itself
require File.dirname(__FILE__) + '/../init'

# An ActiveRecord model 
require File.dirname(__FILE__) + '/../lib/person'

# Basically equivalent to a migration. Creates the schema/tables.
load(File.dirname(__FILE__) + '/schema.rb')

vendor/plugins/acts_as_ordered_tree/test/database.yml

database:
  adapter: sqlite3
  database: ":memory:"

vendor/plugins/acts_as_ordered_tree/test/schema.rb

ActiveRecord::Schema.define(:version => 1) do
  create_table "people", :force => true do |t|
    t.column "parent_id" ,:integer ,:null => false ,:default => 0
    t.column "position"  ,:integer
    t.column "name"      ,:string
  end
  add_index "people", ["parent_id"], :name => "index_people_on_parent_id"
end


vendor/plugins/acts_as_ordered_tree/lib/person.rb

class Person < ActiveRecord::Base
  acts_as_ordered_tree
end
 
Facts about Rails plugins / Plugin toolsRDF feed
Description [Oops! No type defined for attribute]
Personal tools