google-code-export / ruby-activeldap

Automatically exported from code.google.com/p/ruby-activeldap
Other
1 stars 1 forks source link

Modifing array #21

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Load an entry from ldap, using ActiveLdap - find method. You get
ActiveLdap object.
2. Modify object's attribute which is mapped array with multiple elements
from LDAP. Add or remove array element, operating still on the same array.
3. Save the object. 

Changes in array LDAP attribute are expected but there aren't. The problem
disappears when the process of modification ActiveLDAP object's attribute
is made by creating new array variable, copying proper elements from
"ancestor" array to it, and then modifing object's attribute with created
new array. 

I guess the problem is with ActiveLdap just before save algorithm. It
decides which attributes are going to be saved by comparing old values with
new one of ActiveLdap object's attributes using reference not actual value. 

I hope the problem was described well. If not, please contact me at
wpiatkowski < at > power.com.pl.

I used 37513 revision from trunk.

Regards

Original issue reported on code.google.com by chmur...@gmail.com on 11 Mar 2009 at 2:59

GoogleCodeExporter commented 9 years ago
Array#== isn't just reference match. It considers value.
Could you show us a small script to reproduce the problem?

Original comment by kou...@gmail.com on 12 Mar 2009 at 12:01

GoogleCodeExporter commented 9 years ago
Sure, this are three tests written in Rails 2.0 that represents the problem more
deeply. Take a look:

  def test_unique_member__modified_by_accessor__array_push
    number_of_added_users = 1

    group = Group.find_one("test_group")
    members_count_before_add = group.uniqueMember.length
    group.uniqueMember << "uid=some_user"
    members_count_after_add = group.uniqueMember.length
    members_count_before_save = members_count_after_add
    assert_equal members_count_before_add + number_of_added_users,
members_count_after_add, "Members are not added properly!"
    group.save!

    group = Group.find_one("test_group")
    members_count_after_save = group.uniqueMember.length
    assert_equal members_count_before_save, members_count_after_save, "Members are
not saved properly!"
  end

  def test_unique_member__modified_by_accessor__copied_reference
    number_of_added_users = 1

    group = Group.find_one("test_group")
    members_count_before_add = group.uniqueMember.length

    members = group.uniqueMember
    members << "uid=some_users"
    group.uniqueMember = members

    members_count_after_add = group.uniqueMember.length
    members_count_before_save = members_count_after_add
    assert_equal members_count_before_add + number_of_added_users,
members_count_after_add, "Members are not added properly!"
    group.save!

    group = Group.find_one("test_group")
    members_count_after_save = group.uniqueMember.length
    assert_equal members_count_before_save, members_count_after_save, "Members are
not saved properly!"
  end

  def test_unique_member__modified_by_accessor__cloned_value_object
    number_of_added_users = 1

    group = Group.find_one("test_group")
    members_count_before_add = group.uniqueMember.length

    members = group.uniqueMember.clone
    members << "uid=some_users"
    group.uniqueMember = members

    members_count_after_add = group.uniqueMember.length
    members_count_before_save = members_count_after_add
    assert_equal members_count_before_add + number_of_added_users,
members_count_after_add, "Members are not added properly!"
    group.save!

    group = Group.find_one("test_group")
    members_count_after_save = group.uniqueMember.length
    assert_equal members_count_before_save, members_count_after_save, "Members are
not saved properly!"
  end

Here is the attr reader for Group class:
  def uniqueMember    
    @data["uniqueMember"] = @data["uniqueMember"].to_a() unless
@data["uniqueMember"].is_a?(Array)
    @data["uniqueMember"]
  end

Following errors appeared:

1) Failure:
test_unique_member__modified_by_accessor__array_push(GroupTest):
Members are not saved properly!. <3> expected but was <2>.
/projects/wpiatkowski/ugm_ldap/test/unit/group_test.rb:137:in
`test_unique_member__modified_by_accessor__array_push

2) Failure:
test_unique_member__modified_by_accessor__copied_reference(GroupTest):
Members are not saved properly!. <3> expected but was <2>.
/projects/wpiatkowski/ugm_ldap/test/unit/group_test.rb:157:in
`test_unique_member__modified_by_accessor__copied_reference'

Test "test_unique_member__modified_by_accessor__cloned_value_object" pass 
successfully

Ofcourse proper setup method creates "test_group" group with two user entries in
uniqueMember attribute before each test.

Original comment by chmur...@gmail.com on 17 Mar 2009 at 9:48

Attachments:

GoogleCodeExporter commented 9 years ago
1. user has_many :wrap for the purpose:
class Group < ActiveLdap::Base
  has_many :unique_members, :wrap => "uniqueMember",
           :class_name => "User", :foreign_key => "dn"
end
group = Group.find("test-group")
group.unique_members << User.find("some-user")

2. I can't reproduce 2) case on my environment.

3. returned attribute value is immutable for now. It may be changed the next 
release.

4. don't use @data directly. use self#[] instead.

Original comment by kou...@gmail.com on 17 Mar 2009 at 2:03