ProblemYou want to inspect the relationships between the objects in your model to confirm you have them set up correctly. You could do this by dummying up a web application, but you want something quick and simple, and nothing beats the command line. SolutionUse the Rails console to create objects of your models and to explore their relationships with one another. From your project root, type: ~/projects$ ruby script/console -s Loading development environment in sandbox. Any modifications you make will be rolled back on exit. If you're using Windows, use: C:\myApp>ruby script/console -s You are then put into an irb session with full access to your project environment and its Active Record models. You can enter Ruby code, just as you would in a controller, to find any problems with your data model. DiscussionAs a demonstration, create a database for a project that tracks assets and their types. This example also associates assets with tags. Create this database by generating three models using script/generate: asset, asset_type, and tag. (Note that you don't want a model for the assets_tags association table because Rails handles it internally.) ~/project$ ruby script/generate model asset ... ~/project$ ruby script/generate model asset_type ... ~/project$ ruby script/generate model tag ... Now, define the specific table definitions with the following migration: class BuildDb < ActiveRecord::Migration def self.up create_table :asset_types do |t| t.column :name, :string end create_table :assets do |t| t.column :asset_type_id, :integer t.column :name, :string t.column :description, :text end create_table :tags do |t| t.column :name, :string end create_table :assets_tags do |t| t.column :asset_id, :integer t.column :tag_id, :integer end end def self.down drop_table :assets_tags drop_table :assets drop_table :asset_types drop_table :tags end end Next, you can populate the database with some dummy data. Use the following SQL insert statements for this: insert into asset_types values (1,'Photo'); insert into asset_types values (2,'Painting'); insert into asset_types values (3,'Print'); insert into asset_types values (4,'Drawing'); insert into asset_types values (5,'Movie'); insert into asset_types values (6,'CD'); insert into assets values (1,1,'Cypress','A photo of a tree.'); insert into assets values (2,5,'Blunder','An action film.'); insert into assets values (3,6,'Snap','A recording of a fire.'); insert into tags values (1,'hot'); insert into tags values (2,'red'); insert into tags values (3,'boring'); insert into tags values (4,'tree'); insert into tags values (5,'organic'); insert into assets_tags values (1,4); insert into assets_tags values (1,5); insert into assets_tags values (2,3); insert into assets_tags values (3,1); insert into assets_tags values (3,2); Now set up the relationships between the models. This example includes a one-to-many and a many-to-many relationship. asset_type.rb: class AssetType < ActiveRecord::Base has_many :assets end tag.rb: class Tag < ActiveRecord::Base has_and_belongs_to_many :assets end asset.rb: class Asset < ActiveRecord::Base belongs_to :asset_type has_and_belongs_to_many :tags end Now that we've got the model set up and have some data loaded, we can open a console session and have a look around: ~/project$ ruby script/console -s Loading development environment in sandbox. Any modifications you make will be rolled back on exit. >> a = Asset.find(3) => #<Asset:0x4093fba8 @attributes={"name"=>8220;Snap", "id"=>"3", "asset_type_id"=>"6", "description"=>"A recording of a fire."}> >> a.name => "Snap" >> a.description => "A recording of a fire." >> a.asset_type => #<AssetType:0x4093a090 @attributes={"name"=>"CD", "id"=>"6"}> >> a.asset_type.name => "CD" >> a.tags => [#<Tag:0x40935acc @attributes={"name"=>"hot", "tag_id"=>"1", "id"=>"1", "asset_id"=>"3"}>, #<Tag:0x40935a90 @attributes={"name"=>"red", "tag_id"=>"2", "id"=>"2", "asset_id"=>"3"}>] >> a.tags.each { |t| puts t.name } hot red => [#<Tag:0x40935acc @attributes={"name"=>"hot", "tag_id"=>"1", "id"=>"1", "asset_id"=>"3"}>, #<Tag:0x40935a90 @attributes={"name"=>"red", "tag_id"=>"2", "id"=>"2", "asset_id"=>"3"}>] In the console session, we retrieve the asset record with an ID of 3 and store it in an object. We display the asset's name and description. Fetching the asset's type returns an AssetType object. The next line returns the name of that asset type. Accessing the tags of this asset object returns an array consisting of the asset's tags. The next command iterates over these tags and prints each tag name. As objects become larger and more complex, their printed representation in the console can become quite difficult to read. Printing model objects to the console with pp (pretty-print) or y (yaml) can greatly improve the readability of the information. Try the following commands in the console: require 'pp' asset = Asset.find(:first) pp asset y asset The y method prints the object in YAML format and is really just a shortcut for: puts asset.to_yaml Examining your model in this stripped-down environment is a great way to make sure that there are no problems. Doing similar testing within the controllers of your application
could make an obvious problem a little harder to find. See Also
|