Skip to content

Commit

Permalink
Arel doesn't has to know if a table or column exists.
Browse files Browse the repository at this point in the history
  • Loading branch information
miloops committed Mar 10, 2010
1 parent c03d4bb commit b706f69
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 9 deletions.
5 changes: 3 additions & 2 deletions lib/arel/algebra/relations/relation.rb
Expand Up @@ -84,7 +84,8 @@ def on(*predicates)

module AttributeAccessable
def [](index)
case index
@cached_attributes ||= {}
@cached_attributes[index] ||= case index
when Symbol, String
find_attribute_matching_name(index)
when Attribute, Expression
Expand All @@ -96,7 +97,7 @@ def [](index)
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)
Expand Down
18 changes: 15 additions & 3 deletions lib/arel/engines/sql/relations/table.rb
Expand Up @@ -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 = {})
Expand All @@ -19,6 +19,7 @@ def initialize(name, options = {})
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
Expand All @@ -29,9 +30,20 @@ def as(table_alias)
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

Expand Down
3 changes: 1 addition & 2 deletions spec/arel/algebra/unit/relations/relation_spec.rb
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion spec/arel/algebra/unit/relations/table_spec.rb
Expand Up @@ -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

Expand Down
21 changes: 20 additions & 1 deletion spec/arel/engines/sql/unit/primitives/attribute_spec.rb
Expand Up @@ -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

Expand All @@ -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

0 comments on commit b706f69

Please sign in to comment.