From 1ee5f5ace8ba4afe8d653752ec9d58733afe1085 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Sun, 2 Nov 2008 11:45:26 -0600 Subject: [PATCH] Add reference generation to model generator. --- .../lib/rails_generator/generated_attribute.rb | 4 ++ .../generators/components/model/USAGE | 4 ++ .../components/model/templates/fixtures.yml | 4 ++ .../components/model/templates/migration.rb | 2 + .../generators/components/model/templates/model.rb | 3 + railties/test/generators/generator_test_helper.rb | 10 ++++ .../test/generators/rails_model_generator_test.rb | 45 ++++++++++++++++++++ 7 files changed, 72 insertions(+), 0 deletions(-) diff --git a/railties/lib/rails_generator/generated_attribute.rb b/railties/lib/rails_generator/generated_attribute.rb index a3d4a01..e7301ac 100644 --- a/railties/lib/rails_generator/generated_attribute.rb +++ b/railties/lib/rails_generator/generated_attribute.rb @@ -41,6 +41,10 @@ module Rails def reference? [ :references, :belongs_to ].include?(self.type) end + + def referenced_by? + [ :has_one, :has_many, :has_and_belongs_to_many ].include?(self.type) + end end end end diff --git a/railties/lib/rails_generator/generators/components/model/USAGE b/railties/lib/rails_generator/generators/components/model/USAGE index 24b03b4..0be4c64 100644 --- a/railties/lib/rails_generator/generators/components/model/USAGE +++ b/railties/lib/rails_generator/generators/components/model/USAGE @@ -9,6 +9,10 @@ Description: You don't have to think up every attribute up front, but it helps to sketch out a few so you can start working with the model immediately. + If you include an attribute with a type of :references, :belongs_to, + :has_many, :has_one, or :has_and_belongs_to_many, the model will contain + the appropriate association declaration. + This generates a model class in app/models, a unit test in test/unit, a test fixture in test/fixtures/singular_name.yml, and a migration in db/migrate. diff --git a/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml b/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml index c210351..eebce75 100644 --- a/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml +++ b/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml @@ -3,12 +3,16 @@ <% unless attributes.empty? -%> one: <% for attribute in attributes -%> + <% unless attribute.referenced_by? %> <%= attribute.name %>: <%= attribute.default %> + <% end -%> <% end -%> two: <% for attribute in attributes -%> + <% unless attribute.referenced_by? %> <%= attribute.name %>: <%= attribute.default %> + <% end -%> <% end -%> <% else -%> # one: diff --git a/railties/lib/rails_generator/generators/components/model/templates/migration.rb b/railties/lib/rails_generator/generators/components/model/templates/migration.rb index 382fd11..ee5c623 100644 --- a/railties/lib/rails_generator/generators/components/model/templates/migration.rb +++ b/railties/lib/rails_generator/generators/components/model/templates/migration.rb @@ -2,7 +2,9 @@ class <%= migration_name %> < ActiveRecord::Migration def self.up create_table :<%= table_name %> do |t| <% for attribute in attributes -%> + <% unless attribute.referenced_by? %> t.<%= attribute.type %> :<%= attribute.name %> + <% end -%> <% end -%> <% unless options[:skip_timestamps] %> t.timestamps diff --git a/railties/lib/rails_generator/generators/components/model/templates/model.rb b/railties/lib/rails_generator/generators/components/model/templates/model.rb index 6fcf393..f369653 100644 --- a/railties/lib/rails_generator/generators/components/model/templates/model.rb +++ b/railties/lib/rails_generator/generators/components/model/templates/model.rb @@ -2,4 +2,7 @@ class <%= class_name %> < ActiveRecord::Base <% attributes.select(&:reference?).each do |attribute| -%> belongs_to :<%= attribute.name %> <% end -%> +<% attributes.select(&:referenced_by?).each do |attribute| -%> + <%= attribute.type %> :<%= attribute.name %> +<% end -%> end diff --git a/railties/test/generators/generator_test_helper.rb b/railties/test/generators/generator_test_helper.rb index 0901b21..2005d5c 100644 --- a/railties/test/generators/generator_test_helper.rb +++ b/railties/test/generators/generator_test_helper.rb @@ -285,4 +285,14 @@ class GeneratorTestCase < Test::Unit::TestCase def assert_generated_column(body, name, type) assert_match /t\.#{type.to_s} :#{name.to_s}/, body, "should have column #{name.to_s} defined" end + + # Asserts that the given column is not defined in the migration. + def assert_no_generated_column(body, name) + assert_no_match /t\.\w :#{name.to_s}/, body, "should not have column #{name.to_s} defined" + end + + # Asserts that the given column is not defined in the fixture. + def assert_no_generated_attribute(body, name) + assert_no_match /#{name.to_s}:/, body.to_yaml, "should not have value for #{name.to_s} defined" + end end diff --git a/railties/test/generators/rails_model_generator_test.rb b/railties/test/generators/rails_model_generator_test.rb index aea2aba..ef6cc7b 100644 --- a/railties/test/generators/rails_model_generator_test.rb +++ b/railties/test/generators/rails_model_generator_test.rb @@ -45,4 +45,49 @@ class RailsModelGeneratorTest < GeneratorTestCase assert body =~ /^\s+belongs_to :supplier/, "#{body.inspect} should contain 'belongs_to :supplier'" end end + + def test_model_with_has_many_attributes_generates_has_many_associations + run_generator('model', %w(Supplier name:string products:has_many)) + + assert_generated_model_for :supplier do |body| + assert body =~ /^\s+has_many :products/, "#{body.inspect} should contain 'has_many :products'" + end + end + + def test_model_with_has_one_attributes_generates_has_one_associations + run_generator('model', %w(User name:string account:has_one)) + + assert_generated_model_for :user do |body| + assert body =~ /^\s+has_one :account/, "#{body.inspect} should contain 'has_one :account'" + end + end + + def test_model_with_has_and_belongs_to_many_attributes_generates_habtm_associations + run_generator('model', %w(Product name:string parts:has_and_belongs_to_many)) + + assert_generated_model_for :product do |body| + assert body =~ /^\s+has_and_belongs_to_many :parts/, "#{body.inspect} should contain 'has_and_belongs_to_many :parts'" + end + end + + def test_has_referencing_attributes_do_not_add_column_to_migration + run_generator('model', %w(Supplier name:string products:has_many account:has_one parts:has_and_belongs_to_many)) + + assert_generated_migration :create_suppliers do |t| + assert_no_generated_column t, :products + assert_no_generated_column t, :account + assert_no_generated_column t, :parts + end + end + + def test_has_referencing_attributes_do_not_add_column_to_fixtures + run_generator('model', %w(Supplier name:string products:has_many account:has_one parts:has_and_belongs_to_many)) + + assert_generated_fixtures_for :suppliers do |f| + assert_no_generated_attribute f, :products + assert_no_generated_attribute f, :account + assert_no_generated_attribute f, :parts + end + end + end -- 1.5.4.3