CLI and API to test and analyze ActiveRecord models.
In your Rails 3+ project, add this to your Gemfile:
gem 'modelist'
Then run:
bundle install
Not needed for CLI. Just used if you are using as an API:
Modelist::quiet = true
Modelist has a command-line interface with options to test for required circular dependencies, models that the specified models require due to nullable or validation constraints, or to test attributes and associations.
Check ActiveRecord circular dependencies. Find circular chains of dependencies where foreign keys that are not primary keys of the models are all not nullable in the schema or not nullable because of ActiveRecord presence validation with:
bundle exec modelist circular
or:
bundle exec modelist circular my_model_1 my_model_2 --output-file=/path/to/errors.log
Example output:
The following non-nullable foreign keys used in ActiveRecord model associations are involved in circular dependencies:
beers.waitress_id -> waitresses.bartender_id -> bartenders.beer_id -> beers.waitress_id
beers.waitress_id -> waitresses.bartender_id -> bartenders.order_id -> order.beer_id -> beers.waitress_id
Distinct foreign keys involved in a circular dependency:
beers.waitress_id
order.beer_id
bartenders.beer_id
bartenders.order_id
waitresses.bartender_id
Foreign keys by number of circular dependency chains involved with:
2 (out of 2): beers.waitress_id -> waitresses
2 (out of 2): waitresses.bartender_id -> bartenders
1 (out of 2): order.beer_id -> beers
1 (out of 2): bartenders.order_id -> order
1 (out of 2): bartenders.beer_id -> beers
Specify --output-file to provide an pathname of an errors file.
Find the models that the specified models have non-nullable or presence validations for directly and indirectly. You can use this to determine which models are really required with:
bundle exec modelist required my_model_1 my_model_2
Example output:
Required models:
Bartender
Beer
Order
Waitress
Test ActiveRecord models, their attributes, and associations with:
bundle exec modelist test
or:
bundle exec modelist test my_model_1 my_model_2 --output-file=/path/to/errors.log
Example output:
(...example data from models and attributes...)
---
FAILED: MyModel
---
MyModel.last.some_associations: PG::Error: ERROR: operator does not exist: character varying = integer
LINE 1: ...oobars" WHERE "foobars"."my_model_id" = 7
^
(...continued and backtrace...)
---
(...more errors...)
Passed (258):
---
AnotherGoodModel
GoodModel
...
Warnings (123):
---
Foo.first was nil. Assuming there is no data in the associated table, but please verify.
Bar's belongs_to :waitresses may need to be singularized to waitress?
...
Failed (85):
---
Bar
Foobar
MyModel
Specify --output-file to provide an pathname of an errors file.
Given a (partial) model/tablename/column/association name, finds all matching models/associations:
bundle exec modelist search partial_search_string
Example output:
Models:
Foo (table: foos)
Foobar (table: foobars)
Associations:
Bar (table: bars), association: foo (macro: belongs_to, options: {})
Loo (table: loos), association: f_users (macro: has_one, options: {:foreign_key=>:foo_id})
Given two model names will find known paths:
bundle exec modelist paths my_model_1 my_model_2
Example output:
checking for path from foobar to barfoo...
+++++++-+-++--+------
Paths from foobar to barfoo (2):
foobar.foo -> foo.barfoos -> barfoo
foobar.barfoo -> barfoo
Modelist::Analyst.find_required_models(:model1, :model2)
Modelist::CircularRefChecker.test_models(:model1, :model2, output_file: true)
Modelist::Tester.test_models(:model1, :model2, output_file: true)
Modelist::Searcher.find_all('foo')
Modelist::PathFinder.find_all(:model1, :model2)
Copyright (c) 2012-2013 Gary S. Weaver, released under the MIT license.