Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

fixes composed_of for delegated attributes and methods #3807

Closed
wants to merge 1 commit into from

7 participants

Patrick Negri Sergey Nartimov José Valim Roman Shatsov Isaac Sanders Rafael Mendonça França Steve Klabnik
Patrick Negri

composed_of wasnt working for delegated attributes and methods again.

this is my first contribution, can any1 check if its valid?

thanks

Sergey Nartimov

It will be good to have test for it

José Valim
Owner

I am fine with this change but we do need to have a test for it, as @lest said.

Patrick Negri

did the tests, but (dont know why), the other tests are getting errors like "stack too deep", maybe i did forgot to do something prior to test preparation. but was not my fault, cant execute the aggregation tests on HEAD/rails too.

anyway, the tests for the delegate and methods are working.

José Valim
Owner

Ah, the stack too deep makes total sense. As the overridden method will probably invoked the composed_of bit.

Patrick Negri
Patrick Negri

Any tip on how to improve those tests?

Roman Shatsov

I made commit and now old and new tests pass. Can I attach code to this pull request without creating new?

Patrick Negri

roshats. Submit a Pull request to my Branch and i will update this pull.
Regards
Patrick

Isaac Sanders

Is this still an issue?

Patrick Negri

dont know maybe we need to remerge again and pull

Rafael Mendonça França

@pnegri @roshats any news about this one?

Ed Tsech edtsech referenced this pull request from a commit in edtsech/rails
Ed Tsech edtsech Fix stack level to deep issue in #3807. 0448f6c
Patrick Negri pnegri closed this
Patrick Negri pnegri reopened this
Rafael Mendonça França

@pnegri could you squash your commits?

Patrick Negri pnegri referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Patrick Negri

hey guys, any update on that?

Steve Klabnik
Collaborator

If #6743 gets merged, this feature won't be useful.

Patrick Negri pnegri referenced this pull request
Merged

Removing composed_of #6743

Steve Klabnik steveklabnik referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Steve Klabnik steveklabnik referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Steve Klabnik steveklabnik closed this pull request from a commit
Steve Klabnik steveklabnik Removing composed_of from ActiveRecord.
This feature adds a lot of complication to ActiveRecord for dubious
value. Let's talk about what it does currently:

class Customer < ActiveRecord::Base
  composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
end

Instead, you can do something like this:

    def balance
      @balance ||= Money.new(value, currency)
    end

    def balance=(balance)
      self[:value] = balance.value
      self[:currency] = balance.currency
      @balance = balance
    end

Since that's fairly easy code to write, and doesn't need anything
extra from the framework, if you use composed_of today, you'll
have to add accessors/mutators like that.

Closes #1436
Closes #2084
Closes #3807
14fc8b3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
12 activerecord/lib/active_record/aggregations.rb
View
@@ -220,17 +220,21 @@ def composed_of(part_id, options = {})
constructor = options[:constructor] || :new
converter = options[:converter]
- reader_method(name, class_name, mapping, allow_nil, constructor)
+ # Is name of method already used by composed_of ?
+ method = mapping.length == 1 && mapping.first.first == name ?
+ :read_attribute : :send
+
+ reader_method(name, class_name, mapping, allow_nil, constructor, method)
writer_method(name, class_name, mapping, allow_nil, converter)
create_reflection(:composed_of, part_id, options, self)
end
private
- def reader_method(name, class_name, mapping, allow_nil, constructor)
+ def reader_method(name, class_name, mapping, allow_nil, constructor, method)
define_method(name) do
- if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|pair| !read_attribute(pair.first).nil? })
- attrs = mapping.collect {|pair| read_attribute(pair.first)}
+ if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|pair| !self.send(method, pair.first).nil? })
+ attrs = mapping.collect {|pair| self.send(method, pair.first)}
object = constructor.respond_to?(:call) ?
constructor.call(*attrs) :
class_name.constantize.send(constructor, *attrs)
56 activerecord/test/cases/aggregations_test.rb
View
@@ -156,3 +156,59 @@ def test_composed_of_aggregation_redefinition_reflections_should_differ_and_not_
DifferentPerson.reflect_on_aggregation(:composed_of)
end
end
+
+class MethodAndDelegationAggregationsTest <ActiveRecord::TestCase
+
+ class FullName
+ attr_reader :fname, :lname
+ def initialize(fname, lname)
+ @fname, @lname = fname, lname
+ end
+
+ def to_s
+ @fname + " " + @lname
+ end
+
+ def ==(other_name)
+ return self.to_s == other_name if (other_name.kind_of? String)
+ fname == other_name.fname && lname == other_name.lname
+ end
+ end
+
+ class DelegateTest
+ def test_delegated
+ "Boop"
+ end
+ end
+
+ class Person < ActiveRecord::Base
+ def first_name
+ "Bart"
+ end
+
+ def first_name=
+ end
+
+ def last_name
+ "Simpsom"
+ end
+
+ def last_name=
+ end
+
+ composed_of :full_name, :class_name => "MethodAndDelegationAggregationsTest::FullName", :mapping => [ %W(first_name fname), %W(last_name lname) ]
+
+ attr_accessor :some_class
+
+ delegate :test_delegated, :to => :some_class
+ composed_of :delegated_name, :class_name => "MethodAndDelegationAggregationsTest::FullName", :mapping => [ %W(first_name fname), %W(test_delegated lname) ]
+ end
+
+ def test_composed_of_with_method_attribute
+ person = Person.new
+ assert_equal person.full_name, "Bart Simpsom"
+ person.some_class = MethodAndDelegationAggregationsTest::DelegateTest.new
+ assert_equal person.delegated_name, "Bart Boop"
+ end
+
+end
Something went wrong with that request. Please try again.