aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/arel/algebra/relations/relation.rb5
-rw-r--r--lib/arel/engines/sql/relations/table.rb18
-rw-r--r--spec/arel/algebra/unit/relations/relation_spec.rb3
-rw-r--r--spec/arel/algebra/unit/relations/table_spec.rb1
-rw-r--r--spec/arel/engines/sql/unit/primitives/attribute_spec.rb21
5 files changed, 39 insertions, 9 deletions
diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb
index e848c8aa1c..4cd3f8e109 100644
--- a/lib/arel/algebra/relations/relation.rb
+++ b/lib/arel/algebra/relations/relation.rb
@@ -84,7 +84,8 @@ module Arel
module AttributeAccessable
def [](index)
- case index
+ @cached_attributes ||= {}
+ @cached_attributes[index] ||= case index
when Symbol, String
find_attribute_matching_name(index)
when Attribute, Expression
@@ -96,7 +97,7 @@ module Arel
end
def find_attribute_matching_name(name)
- attributes.detect { |a| a.named?(name) }
+ attributes.detect { |a| a.named?(name) } || Attribute.new(self, name)
end
def find_attribute_matching_attribute(attribute)
diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb
index e4b75d6c3d..d10b761ea3 100644
--- a/lib/arel/engines/sql/relations/table.rb
+++ b/lib/arel/engines/sql/relations/table.rb
@@ -2,7 +2,7 @@ module Arel
class Table < Relation
include Recursion::BaseCase
- cattr_accessor :engine
+ cattr_accessor :engine, :tables
attr_reader :name, :engine, :table_alias, :options
def initialize(name, options = {})
@@ -19,6 +19,7 @@ module Arel
if @engine.connection
begin
require "arel/engines/sql/compilers/#{@engine.adapter_name.downcase}_compiler"
+ @@tables ||= engine.tables
rescue LoadError
raise "#{@engine.adapter_name} is not supported by Arel."
end
@@ -29,9 +30,20 @@ module Arel
Table.new(name, options.merge(:as => table_alias))
end
+ def table_exists?
+ if @table_exists
+ true
+ else
+ @table_exists = @@tables.include?(name) || engine.table_exists?(name)
+ end
+ end
+
def attributes
- @attributes ||= columns.collect do |column|
- Attribute.new(self, column.name.to_sym)
+ return @attributes if defined?(@attributes)
+ if table_exists?
+ @attributes = columns.collect { |column| Attribute.new(self, column.name.to_sym) }
+ else
+ []
end
end
diff --git a/spec/arel/algebra/unit/relations/relation_spec.rb b/spec/arel/algebra/unit/relations/relation_spec.rb
index cf6509fe6a..a1d1793d92 100644
--- a/spec/arel/algebra/unit/relations/relation_spec.rb
+++ b/spec/arel/algebra/unit/relations/relation_spec.rb
@@ -16,10 +16,9 @@ module Arel
end
describe 'when given a', Symbol, String do
- it "returns the attribute with the same name, if it exists" do
+ it "returns the attribute with the same name" do
check @relation[:id].should == @attribute1
check @relation['id'].should == @attribute1
- @relation[:does_not_exist].should be_nil
end
end
end
diff --git a/spec/arel/algebra/unit/relations/table_spec.rb b/spec/arel/algebra/unit/relations/table_spec.rb
index 19c1ba2bea..d93446f1b9 100644
--- a/spec/arel/algebra/unit/relations/table_spec.rb
+++ b/spec/arel/algebra/unit/relations/table_spec.rb
@@ -10,7 +10,6 @@ module Arel
describe 'when given a', Symbol do
it "manufactures an attribute if the symbol names an attribute within the relation" do
check @relation[:id].should == Attribute.new(@relation, :id)
- @relation[:does_not_exist].should be_nil
end
end
diff --git a/spec/arel/engines/sql/unit/primitives/attribute_spec.rb b/spec/arel/engines/sql/unit/primitives/attribute_spec.rb
index 9f864dd3a1..8daa0d9fd5 100644
--- a/spec/arel/engines/sql/unit/primitives/attribute_spec.rb
+++ b/spec/arel/engines/sql/unit/primitives/attribute_spec.rb
@@ -9,7 +9,7 @@ module Arel
describe '#column' do
it "returns the corresponding column in the relation" do
- @attribute.column.should == @relation.column_for(@attribute)
+ @attribute.column.should == @relation.column_for(@attribute)
end
end
@@ -31,6 +31,25 @@ module Arel
end
end
end
+
+ describe 'for an inexistent attribute' do
+ it "manufactures sql" do
+ sql = @relation[:does_not_exist].to_sql
+
+ adapter_is :mysql do
+ sql.should be_like(%Q{`users`.`does_not_exist`})
+ end
+
+ adapter_is :oracle do
+ sql.should be_like(%Q{"USERS"."DOEST_NOT_EXIST"})
+ end
+
+ adapter_is_not :mysql, :oracle do
+ sql.should be_like(%Q{"users"."does_not_exist"})
+ end
+ end
+ end
+
end
end
end