Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Multi-value support

  • Loading branch information...
commit 678953c090d3f75742802f440c4f357e02048e6e 1 parent ad07ada
@ernie authored
Showing with 46 additions and 32 deletions.
  1. +34 −32 lib/valium.rb
  2. +12 −0 spec/valium/valium_spec.rb
View
66 lib/valium.rb
@@ -6,24 +6,25 @@ module Valium
if ActiveRecord::VERSION::MINOR == 0 # We need to use the old deserialize code
- def [](attr_name)
- attr_name = attr_name.to_s
- column = columns_hash[attr_name]
- if column.text? && serialized_attributes.include?(attr_name)
- serialized_klass = serialized_attributes[attr_name]
- end
+ def [](*attr_names)
+ attr_names = attr_names.map(&:to_s)
- connection.select_values(
- select(arel_table[attr_name]).to_sql
- ).map! do |value|
- if value.nil? || !column
- value
- elsif serialized_klass
- deserialize_value(value, serialized_klass)
- else
- column.type_cast(value)
+ results = connection.select_rows(
+ select(attr_names.map {|n| arel_table[n]}).to_sql
+ ).map! do |values|
+ values.each_with_index do |value, index|
+ if value.nil? || !columns_hash[attr_names[index]]
+ # Don't modify
+ elsif serialized_attributes[attr_names[index]]
+ values[index] = deserialize_value(value, serialized_attributes[attr_names[index]])
+ else
+ values[index] = columns_hash[attr_names[index]].type_cast(value)
+ end
end
+ values
end
+
+ attr_names.size > 1 ? results : results.flatten!
end
def deserialize_value(value, klass)
@@ -42,32 +43,33 @@ def deserialize_value(value, klass)
else # we're on 3.1+, yay for coder.load!
- def [](attr_name)
- attr_name = attr_name.to_s
- column = columns_hash[attr_name]
- if column.text? && serialized_attributes.include?(attr_name)
- coder = serialized_attributes[attr_name]
- end
+ def [](*attr_names)
+ attr_names = attr_names.map(&:to_s)
- connection.select_values(
- select(arel_table[attr_name]).to_sql
- ).map! do |value|
- if value.nil? || !column
- value
- elsif coder
- coder.load(value)
- else
- column.type_cast(value)
+ results = connection.select_rows(
+ select(attr_names.map {|n| arel_table[n]}).to_sql
+ ).map! do |values|
+ values.each_with_index do |value, index|
+ if value.nil? || !columns_hash[attr_names[index]]
+ # Don't modify
+ elsif serialized_attributes[attr_names[index]]
+ values[index] = serialized_attributes[attr_names[index]].load(value)
+ else
+ values[index] = columns_hash[attr_names[index]].type_cast(value)
+ end
end
+ values
end
+
+ attr_names.size > 1 ? results : results.flatten!
end
end # Minor version check
module Relation
def [](*args)
- if args.size == 1 && [String, Symbol].any? {|c| c === args.first}
- scoping { @klass[args.first] }
+ if args.size > 0 && args.all? {|a| String === a || Symbol === a}
+ scoping { @klass[*args] }
else
to_a[*args]
end
View
12 spec/valium/valium_spec.rb
@@ -14,6 +14,12 @@
it { should eq (1..1000).to_a }
end
+ context 'with multiple keys' do
+ subject { Person[:id, :last_name] }
+ it { should have(1000).elements }
+ it { should eq (1..1000).map {|n| [n, "Number#{n}"]}}
+ end
+
context 'with a datetime column' do
subject { Person[:created_at] }
it { should have(1000).datetimes }
@@ -32,6 +38,12 @@
it { should eq ['Number1', 'Number500', 'Number1000'] }
end
+ context 'with a scope and multiple keys' do
+ subject { Person.where(:id => [1,500,1000])[:last_name, :id, :extra_info] }
+ it { should have(3).elements }
+ it { should eq [1,500,1000].map {|n| ["Number#{n}", n, {:a_key => "Value Number #{n}"}]}}
+ end
+
context 'with a relation array index' do
subject { Person.where(:id => [1,500,1000])[1] }
it { should eq Person.find(500) }
Please sign in to comment.
Something went wrong with that request. Please try again.