aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-07-14 23:00:08 -0300
committerEmilio Tagua <miloops@gmail.com>2009-07-14 23:00:08 -0300
commit634f6713ee15c6fd958bafc7a3422acac2e3343f (patch)
tree0df11ceb12f9911ad16c950802af1e5874c89ab4 /activerecord/lib/active_record
parentfb46d00fdfa724dc0c252a46ec13c4ee4cda4708 (diff)
parent40b387580ff251e06632fbcc87c2a78c027a6b27 (diff)
downloadrails-634f6713ee15c6fd958bafc7a3422acac2e3343f.tar.gz
rails-634f6713ee15c6fd958bafc7a3422acac2e3343f.tar.bz2
rails-634f6713ee15c6fd958bafc7a3422acac2e3343f.zip
Merge commit 'rails/master'
Diffstat (limited to 'activerecord/lib/active_record')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb9
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb13
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb6
-rw-r--r--activerecord/lib/active_record/serializers/xml_serializer.rb113
4 files changed, 26 insertions, 115 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 97fdd9b1ba..31d3a89b9d 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1273,9 +1273,16 @@ module ActiveRecord
if send(reflection.name).loaded? || reflection.options[:finder_sql]
send(reflection.name).map(&:id)
else
- send(reflection.name).all(:select => "#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").map(&:id)
+ if reflection.through_reflection && reflection.source_reflection.belongs_to?
+ through = reflection.through_reflection
+ primary_key = reflection.source_reflection.primary_key_name
+ send(through.name).all(:select => "DISTINCT #{through.quoted_table_name}.#{primary_key}").map!(&:"#{primary_key}")
+ else
+ send(reflection.name).all(:select => "#{reflection.quoted_table_name}.#{reflection.klass.primary_key}").map!(&:id)
+ end
end
end
+
end
def collection_accessor_methods(reflection, association_proxy_class, writer = true)
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 15358979c2..ecd2d57a5a 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -133,6 +133,7 @@ module ActiveRecord
end
private
+
# Suffixes a, ?, c become regexp /(a|\?|c)$/
def rebuild_attribute_method_regexp
suffixes = attribute_method_suffixes.map { |s| Regexp.escape(s) }
@@ -238,19 +239,17 @@ module ActiveRecord
def method_missing(method_id, *args, &block)
method_name = method_id.to_s
- if self.class.private_method_defined?(method_name)
- raise NoMethodError.new("Attempt to call private method", method_name, args)
- end
-
# If we haven't generated any methods yet, generate them, then
# see if we've created the method we're looking for.
if !self.class.generated_methods?
self.class.define_attribute_methods
+ guard_private_attribute_method!(method_name, args)
if self.class.generated_methods.include?(method_name)
return self.send(method_id, *args, &block)
end
end
+ guard_private_attribute_method!(method_name, args)
if self.class.primary_key.to_s == method_name
id
elsif md = self.class.match_attribute_method?(method_name)
@@ -371,6 +370,12 @@ module ActiveRecord
end
private
+ # prevent method_missing from calling private methods with #send
+ def guard_private_attribute_method!(method_name, args)
+ if self.class.private_method_defined?(method_name)
+ raise NoMethodError.new("Attempt to call private method", method_name, args)
+ end
+ end
def missing_attribute(attr_name, stack)
raise ActiveRecord::MissingAttributeError, "missing attribute: #{attr_name}", stack
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index 2d90ef35aa..5d88012e4f 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -78,11 +78,14 @@ HEADER
begin
tbl = StringIO.new
+ # first dump primary key column
if @connection.respond_to?(:pk_and_sequence_for)
pk, pk_seq = @connection.pk_and_sequence_for(table)
+ elsif @connection.respond_to?(:primary_key)
+ pk = @connection.primary_key(table)
end
pk ||= 'id'
-
+
tbl.print " create_table #{table.inspect}"
if columns.detect { |c| c.name == pk }
if pk != 'id'
@@ -94,6 +97,7 @@ HEADER
tbl.print ", :force => true"
tbl.puts " do |t|"
+ # then dump all non-primary key columns
column_specs = columns.map do |column|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
next if column.name == pk
diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb
index c3811caa53..253fa03785 100644
--- a/activerecord/lib/active_record/serializers/xml_serializer.rb
+++ b/activerecord/lib/active_record/serializers/xml_serializer.rb
@@ -164,42 +164,9 @@ module ActiveRecord #:nodoc:
end
end
- class XmlSerializer < ActiveModel::Serializer #:nodoc:
+ class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
include Serialization::RecordSerializer
- def builder
- @builder ||= begin
- require 'builder' unless defined? ::Builder
- options[:indent] ||= 2
- builder = options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])
-
- unless options[:skip_instruct]
- builder.instruct!
- options[:skip_instruct] = true
- end
-
- builder
- end
- end
-
- def root
- root = (options[:root] || @serializable.class.to_s.underscore).to_s
- reformat_name(root)
- end
-
- def dasherize?
- !options.has_key?(:dasherize) || options[:dasherize]
- end
-
- def camelize?
- options.has_key?(:camelize) && options[:camelize]
- end
-
- def reformat_name(name)
- name = name.camelize if camelize?
- dasherize? ? name.dasherize : name
- end
-
def serializable_attributes
serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) }
end
@@ -211,28 +178,6 @@ module ActiveRecord #:nodoc:
end
end
- def add_attributes
- (serializable_attributes + serializable_method_attributes).each do |attribute|
- add_tag(attribute)
- end
- end
-
- def add_procs
- if procs = options.delete(:procs)
- [ *procs ].each do |proc|
- proc.call(options)
- end
- end
- end
-
- def add_tag(attribute)
- builder.tag!(
- reformat_name(attribute.name),
- attribute.value.to_s,
- attribute.decorations(!options[:skip_types])
- )
- end
-
def add_associations(association, records, opts)
if records.is_a?(Enumerable)
tag = reformat_name(association.to_s)
@@ -282,50 +227,10 @@ module ActiveRecord #:nodoc:
end
end
- class Attribute #:nodoc:
- attr_reader :name, :value, :type
-
- def initialize(name, record)
- @name, @record = name, record
-
- @type = compute_type
- @value = compute_value
- end
-
- # There is a significant speed improvement if the value
- # does not need to be escaped, as <tt>tag!</tt> escapes all values
- # to ensure that valid XML is generated. For known binary
- # values, it is at least an order of magnitude faster to
- # Base64 encode binary values and directly put them in the
- # output XML than to pass the original value or the Base64
- # encoded value to the <tt>tag!</tt> method. It definitely makes
- # no sense to Base64 encode the value and then give it to
- # <tt>tag!</tt>, since that just adds additional overhead.
- def needs_encoding?
- ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
- end
-
- def decorations(include_types = true)
- decorations = {}
-
- if type == :binary
- decorations[:encoding] = 'base64'
- end
-
- if include_types && type != :string
- decorations[:type] = type
- end
-
- if value.nil?
- decorations[:nil] = true
- end
-
- decorations
- end
-
+ class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
protected
def compute_type
- type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type
+ type = @serializable.class.serialized_attributes.has_key?(name) ? :yaml : @serializable.class.columns_hash[name].type
case type
when :text
@@ -336,22 +241,12 @@ module ActiveRecord #:nodoc:
type
end
end
-
- def compute_value
- value = @record.send(name)
-
- if formatter = Hash::XML_FORMATTING[type.to_s]
- value ? formatter.call(value) : nil
- else
- value
- end
- end
end
class MethodAttribute < Attribute #:nodoc:
protected
def compute_type
- Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string
+ Hash::XML_TYPE_NAMES[@serializable.send(name).class.name] || :string
end
end
end