diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2007-09-28 14:07:23 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2007-09-28 14:07:23 +0000 |
commit | bbdb4e55f6eceb40c2047c614f5b47cef253dfb0 (patch) | |
tree | 76c4044567b02f92dab779c85505942a0c3629d7 /activerecord/lib/active_record/serialization.rb | |
parent | 078bd0515e8342165a4bc3b8fcc4faa318ebb188 (diff) | |
download | rails-bbdb4e55f6eceb40c2047c614f5b47cef253dfb0.tar.gz rails-bbdb4e55f6eceb40c2047c614f5b47cef253dfb0.tar.bz2 rails-bbdb4e55f6eceb40c2047c614f5b47cef253dfb0.zip |
Added :include option to to_json (closes #9677) [chuyeow]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7663 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/serialization.rb')
-rw-r--r-- | activerecord/lib/active_record/serialization.rb | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb index f10d1b3b7e..2c8210a299 100644 --- a/activerecord/lib/active_record/serialization.rb +++ b/activerecord/lib/active_record/serialization.rb @@ -2,7 +2,7 @@ module ActiveRecord #:nodoc: module Serialization class Serializer #:nodoc: attr_reader :options - + def initialize(record, options = {}) @record, @options = record, options.dup end @@ -23,31 +23,70 @@ module ActiveRecord #:nodoc: options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column) attribute_names = attribute_names - options[:except].collect { |n| n.to_s } end - + attribute_names end def serializable_method_names Array(options[:methods]).inject([]) do |method_attributes, name| - method_attributes << :name if @record.respond_to?(name.to_s) + method_attributes << name if @record.respond_to?(name.to_s) method_attributes end end - + def serializable_names serializable_attribute_names + serializable_method_names end + # Add associations specified via the :includes option. + # Expects a block that takes as arguments: + # +association+ - name of the association + # +records+ - the association record(s) to be serialized + # +opts+ - options for the association records + def add_includes(&block) + if include_associations = options.delete(:include) + base_only_or_except = { :except => options[:except], + :only => options[:only] } + + include_has_options = include_associations.is_a?(Hash) + associations = include_has_options ? include_associations.keys : Array(include_associations) + + for association in associations + records = case @record.class.reflect_on_association(association).macro + when :has_many, :has_and_belongs_to_many + @record.send(association).to_a + when :has_one, :belongs_to + @record.send(association) + end + + unless records.nil? + association_options = include_has_options ? include_associations[association] : base_only_or_except + opts = options.merge(association_options) + yield(association, records, opts) + end + end + + options[:include] = include_associations + end + end + def serializable_record returning(serializable_record = {}) do serializable_names.each { |name| serializable_record[name] = @record.send(name) } + add_includes do |association, records, opts| + if records.is_a?(Enumerable) + serializable_record[association] = records.collect { |r| self.class.new(r, opts).serializable_record } + else + serializable_record[association] = self.class.new(records, opts).serializable_record + end + end end end def serialize # overwrite to implement - end - + end + def to_s(&block) serialize(&block) end |