Permalink
Browse files

Added new ActiveRecord::View class as abstract superclass for views. …

…Adapted view naming to plural convention.
  • Loading branch information...
mschuerig committed Apr 7, 2009
1 parent b52f315 commit 7ca62e65219837dfdcd134fbb89df712ba5de328
View
@@ -0,0 +1,54 @@
+
+module ActiveRecord
+ class View < Base
+ self.abstract_class = true
+
+ def readonly?
+ true
+ end
+
+ class << self
+ def based_on(model)
+ define_method("to_#{model.name.demodulize.underscore}") do
+ ### TODO reload?
+ becomes(model)
+ end
+
+ model.reflect_on_all_associations.each do |assoc|
+ steal_association(model, assoc)
+ end
+ end
+
+ def steal_association(model, *associations)
+ associations.each do |association|
+ r = case association
+ when String, Symbol
+ model.reflect_on_association(association.to_sym)
+ when ActiveRecord::Reflection::AssociationReflection
+ association
+ else
+ raise ArgumentError, "Unrecognized association #{association.inspect}; must be a Symbol, String, or AssociationReflection."
+ end
+ case r.macro
+ when :belongs_to
+ ### ensure that the fk column exists
+ when :has_many
+ ### TODO add options for :through assocs
+ options = r.options.merge(
+ :class_name => r.class_name,
+ :foreign_key => r.primary_key_name
+ )
+ has_many r.name, options
+ when :has_and_belongs_to_many
+ options = r.options.merge(
+ :class_name => r.class_name,
+ :foreign_key => r.primary_key_name,
+ :association_foreign_key => r.association_foreign_key
+ )
+ has_and_belongs_to_many r.name, options
+ end
+ end
+ end
+ end
+ end
+end
View
@@ -10,7 +10,7 @@ def test_tables
create_view
found = ActiveRecord::Base.connection.tables.sort
found.delete(ActiveRecord::Migrator.schema_migrations_table_name)
- assert_equal ["people", "people2", "places", "v_person"], found
+ assert_equal ["people", "people2", "places", "v_people"], found
end
def test_base_tables
create_view
@@ -20,54 +20,54 @@ def test_base_tables
end
def test_views
create_view
- assert_equal ['v_person'], ActiveRecord::Base.connection.views
+ assert_equal ['v_people'], ActiveRecord::Base.connection.views
end
def test_columns
create_view
- assert_equal ["f_name", "l_name", "social_security"], ActiveRecord::Base.connection.columns('v_person').collect { |c| c.name }
+ assert_equal ["f_name", "l_name", "social_security"], ActiveRecord::Base.connection.columns('v_people').collect { |c| c.name }
end
def test_supports_views
assert ActiveRecord::Base.connection.supports_views?
end
def test_mapped_views
create_mapping
- assert_equal ['v_person'], ActiveRecord::Base.connection.views
+ assert_equal ['v_people'], ActiveRecord::Base.connection.views
end
def test_mapped_columns
create_mapping
- assert_equal ["f_name", "l_name"], ActiveRecord::Base.connection.columns('v_person').collect { |c| c.name }
+ assert_equal ["f_name", "l_name"], ActiveRecord::Base.connection.columns('v_people').collect { |c| c.name }
end
def test_view_select_statement
case ActiveRecord::Base.connection.adapter_name
when "MySQL":
- assert_equal "select `people`.`first_name` AS `f_name`,`people`.`last_name` AS `l_name`,`people`.`ssn` AS `social_security` from `people`", ActiveRecord::Base.connection.view_select_statement('v_person')
+ assert_equal "select `people`.`first_name` AS `f_name`,`people`.`last_name` AS `l_name`,`people`.`ssn` AS `social_security` from `people`", ActiveRecord::Base.connection.view_select_statement('v_people')
when "PostgreSQL":
- assert_equal "SELECT people.first_name AS f_name, people.last_name AS l_name, people.ssn AS social_security FROM people;", ActiveRecord::Base.connection.view_select_statement('v_person')
+ assert_equal "SELECT people.first_name AS f_name, people.last_name AS l_name, people.ssn AS social_security FROM people;", ActiveRecord::Base.connection.view_select_statement('v_people')
end
end
def test_old_name_not_found_error_during_mapping
assert_raise ActiveRecord::ActiveRecordError do
- ActiveRecord::Base.connection.create_mapping_view(:people, :v_person, :force => true) do |v|
+ ActiveRecord::Base.connection.create_mapping_view(:people, :v_people, :force => true) do |v|
v.map_column :foo, :bar
end
end
end
private
def create_view
-# ActiveRecord::Base.connection.create_view(:v_person, 'select * from people', :force => true) do |v|
- ActiveRecord::Base.connection.create_view(:v_person, 'select first_name, last_name, ssn from people', :force => true) do |v|
+# ActiveRecord::Base.connection.create_view(:v_people, 'select * from people', :force => true) do |v|
+ ActiveRecord::Base.connection.create_view(:v_people, 'select first_name, last_name, ssn from people', :force => true) do |v|
v.column :f_name
v.column :l_name
v.column :social_security
end
end
def create_mapping
- ActiveRecord::Base.connection.create_mapping_view(:people, :v_person, :force => true) do |v|
+ ActiveRecord::Base.connection.create_mapping_view(:people, :v_people, :force => true) do |v|
v.map_column :id, nil
v.map_column :first_name, :f_name
v.map_column :last_name, :l_name
View
@@ -1,3 +1,5 @@
-class VPerson < ActiveRecord::Base
- set_table_name 'v_person'
-end
+require 'active_record/view'
+
+class VPerson < ActiveRecord::View
+
+end
@@ -30,7 +30,7 @@
t.string "country", :limit => 2
end
- create_view "v_person", "select `people`.`first_name` AS `f_name`,`people`.`last_name` AS `l_name`,`people`.`ssn` AS `social_security` from `people`", :force => true do |v|
+ create_view "v_people", "select `people`.`first_name` AS `f_name`,`people`.`last_name` AS `l_name`,`people`.`ssn` AS `social_security` from `people`", :force => true do |v|
v.column :f_name
v.column :l_name
v.column :social_security
@@ -30,7 +30,7 @@
t.string "country", :limit => 2
end
- create_view "v_person", "SELECT people.first_name AS f_name, people.last_name AS l_name, people.ssn AS social_security FROM people;", :force => true do |v|
+ create_view "v_people", "SELECT people.first_name AS f_name, people.last_name AS l_name, people.ssn AS social_security FROM people;", :force => true do |v|
v.column :f_name
v.column :l_name
v.column :social_security
View
@@ -4,18 +4,18 @@
Debugger.start
class SchemaDumperTest < Test::Unit::TestCase
def setup
- ActiveRecord::Base.connection.execute('drop view if exists v_person')
+ ActiveRecord::Base.connection.execute('drop view if exists v_people')
ActiveRecord::Base.connection.execute('drop view if exists v_profile')
end
def test_view
- create_person_view
+ create_people_view
stream = StringIO.new
dumper = ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
stream.rewind
assert_equal File.open(File.dirname(__FILE__) + "/schema.#{$connection}.expected.rb", 'r').readlines, stream.readlines
end
def test_dump_and_load
- create_person_view
+ create_people_view
assert_dump_and_load_succeed
end
def test_union
@@ -32,19 +32,19 @@ def test_union
assert_dump_and_load_succeed
end
def test_symbol_ignore
- ActiveRecord::SchemaDumper.ignore_views << :v_person
- create_person_view
+ ActiveRecord::SchemaDumper.ignore_views << :v_people
+ create_people_view
assert_dump_and_load_succeed
ActiveRecord::SchemaDumper.ignore_views.pop
end
def test_regex_ignore
- ActiveRecord::SchemaDumper.ignore_views << Regexp.new(/v_person/)
- create_person_view
+ ActiveRecord::SchemaDumper.ignore_views << Regexp.new(/v_people/)
+ create_people_view
assert_dump_and_load_succeed
ActiveRecord::SchemaDumper.ignore_views.pop
end
def test_non_allowed_object_raises_error
- create_person_view
+ create_people_view
ActiveRecord::SchemaDumper.ignore_views << 0
begin
schema_file = File.dirname(__FILE__) + "/schema.#{$connection}.out.rb"
View
@@ -16,8 +16,8 @@
require 'models/v_person'
class Test::Unit::TestCase
- def create_person_view
- ActiveRecord::Base.connection.create_view(:v_person,
+ def create_people_view
+ ActiveRecord::Base.connection.create_view(:v_people,
'select first_name, last_name, ssn from people', :force => true) do |v|
v.column :f_name
v.column :l_name
View
@@ -4,7 +4,7 @@ class ViewTest < Test::Unit::TestCase
def test_create_view
Person.create(:first_name => 'John', :last_name => 'Doe', :ssn => '123456789')
assert_nothing_raised do
- ActiveRecord::Base.connection.create_view(:v_person,
+ ActiveRecord::Base.connection.create_view(:v_people,
'select first_name, last_name, ssn from people', :force => true) do |v|
v.column :f_name
v.column :l_name

0 comments on commit 7ca62e6

Please sign in to comment.