| Last Update: | Wed May 14 13:36:02 -0500 2008 |
Rails plugin to allow for extensible models, where inter-model relations are inferred from the database‘s structure, and not necessarily from explicit declarations in the models.
This means, when one of your models acts_as_magic_model, this plugin will try to infer all the basic relations (has_many, belongs_to and has_and_belongs_to_many) its base table has with other tables in the database, adapting the model correspondingly.
The easiest way is through Rails’ own +scripts/plugins+ utility. The first thing you should do is to tell Rails where the plugin‘s tree is located.
If you want to follow the latest changes, you will probably prefer following the project‘s trunk, however, for production, I strongly suggest you to stick to a stable release. Depending on what you prefer, from your project‘s base directory, type:
$ ./script/plugin source http://magicmodel.rubyforge.org/svn/trunk/
Or, to follow a given release (say, 0.2 - Of course, check on the latest stable release before doing this):
$ ./script/plugin source http://magicmodel.rubyforge.org/svn/tags/0.2/
Then, ask Rails to install the plugin:
$ ./script/plugin install acts_as_magic_model
If you use Subversion for tracking your project‘s development, you will probably want to mark the plugin as an external repository. To do so, add the -x switch:
$ ./script/plugin install -x acts_as_magic_model
In order to use this plugin, you only have to declare it in your model. As an example, say you have the proverbial project-management system, where you have projects (each of which can be of several different types) and people, and a HABTM relation between people and projects. So, you have the following tables (expressed as migrations here):
create_table :people, :force => true do |t|
t.column :name, :string
end
create_table :project_types, :force => true do |t|
t.column :name, :string
end
create_table :projects, :force => true do |t|
t.column :name, :string
t.column :project_type_id, :integer
end
create_table :people_projects, :force => true, :id => false do |t|
t.column :person_id, :integer
t.column :project_id, :integer
end
Using acts_as_magic_model, you can skip declaring the relations in your models, like this: (of course, each of the classes still has to be declared in its own file)
class Person < ActiveRecord::Base
acts_as_magic_model
end
class Project < ActiveRecord::Base
acts_as_magic_model
end
class ProjectType < ActiveRecord::Base
acts_as_magic_model
end
And the gaps will be filled in for you - that is, you can go on and ask for Project.find(:first).people, ProjectType.find(:first).projects.size, Person.find(:first).projects.map {|pr| pr.project_type}, and whatever you fancy.
If any table is related to the models you are declaring as magic does not have a corresponding model explicitly declared, an empty one will be generated - That is, if you create a new table:
create_table :items, :force => true do |t|
t.column :name, :string
t.column :description, :string
end
add_column :people, :item_id
When you call Person for the first time, it will create a Item model, just as if you had declared it like:
class Item < ActiveRecord::Base
has_many :people
end
But keep in mind that Item will not exist before Person is first touched.
This plugin is Copyright (c) 2008 Gunnar Wolf <gwolf@gwolf.org>
This plugin is under a MIT license. For further information, please check the LICENSE file.
The plugin project‘s home page can be found at rubyforge.org/projects/magicmodel/
The development branch of the SVN tree can be pulled anonymously from magicmodel.rubyforge.org/svn/trunk/
Released versions can be found along the ‘tags’ directory of the SVN tree, at magicmodel.rubyforge.org/svn/tags/