[Nitro] Posible belongs_to problem/bug

Humber Aquino humberaquino at gmail.com
Wed Dec 28 09:50:01 EST 2005


I think this can be a bug, please follow mi explanation and don't get bored!  +)

I'll wil show a common use of a has_many - belongs_to relationship

class User
   property :name, String
   property :telephone, String
   property :username, String, :uniq => true
   property :password, String

  #roles: plural of Role
   has_many :roles, Role
end

class Role
   property :permissions, String

   #When og maps this class it will create a column named user_oid 	
   belongs_to :user, User
end

#User fixture user.yml
user1:
  name: John Doe
  telephone: '132312'
  username: jduser
  password: jdpassword
user2:
  name: Some person
  telephone: '13d2312'
  username: spuser
  password: sppassword

#Role fixture role.yml
role1:
  user_oid: 1
  permmisions: something
role2:
  user_oid: 1
  permmisions: something else

#So when whe test this we have no problems ;-)

class TestUsuario < Test::Unit::TestCase
  def setup
    @og = Og.setup(
      :destroy => true,
      :store => :mysql, #4.0.20
      :name => 'test_db',
      :user => 'webuser',
      :password => '******'
    )
    og_fixture User
    og_fixture Role
  end

  def test_roles
    assert_equal 2, @user1.roles.size
  end
end

I run the test an i get this:
1 tests, 1 assertions, 0 failures, 0 errors

:-) Sorry for the verbosity

Then i change the name of the role property in my User class
has_many :roles, Role   ->   has_many :roles_i_love, Role

And in the test case

def test_roles
    assert_equal 2, @user1.roles_i_love.size
end

I run the test.... again  :D
1 tests, 1 assertions, 0 failures, 0 errors
Great!

Now i change the name of the property user in the role class
belongs_to :user, User   ->   belongs_to :user_owner, User

I run the test.... again  :D and:
E, [2005-12-28T18:54:58.992435 #10695] ERROR -- : DB error Unknown
column 'user_oid' in 'where clause', [SELECT COUNT(*) FROM ogrole
WHERE user_oid = 1]
E, [2005-12-28T18:54:58.994148 #10695] ERROR -- :
/usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/store/mysql.rb:181:in
`query'
/usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/store/mysql.rb:181:in `query'
/usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/store/sql.rb:476:in `count'
/usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/entity.rb:166:in `count'
(eval):47:in `count_roles_i_love'
/usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/collection.rb:212:in `size'
test/tc_users.rb:26:in `test_roles'
/usr/lib/ruby/1.8/test/unit/testcase.rb:70:in `run'
/usr/lib/ruby/1.8/test/unit/testsuite.rb:32:in `run'
/usr/lib/ruby/1.8/test/unit/testsuite.rb:31:in `run'
/usr/lib/ruby/1.8/test/unit/testsuite.rb:32:in `run'
/usr/lib/ruby/1.8/test/unit/testsuite.rb:31:in `run'
/usr/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:44:in `run_suite'
/usr/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:65:in `start_mediator'
/usr/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:39:in `start'
/usr/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb:27:in `run'
/usr/lib/ruby/1.8/test/unit/autorunner.rb:200:in `run'
/usr/lib/ruby/1.8/test/unit/autorunner.rb:13:in `run'
/usr/lib/ruby/1.8/test/unit.rb:285
test/tc_users.rb:25
/usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/store/sql.rb:822:in
`handle_sql_exception': Og::StoreException (Og::StoreException)
        from /usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/store/mysql.rb:183:in
`query'
        from /usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/store/sql.rb:476:in
`count'
        from /usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/entity.rb:166:in
`count'
        from (eval):47:in `count_roles_i_love'
        from /usr/lib/ruby/gems/1.8/gems/og-0.26.0/lib/og/collection.rb:212:in
`size'
        from test/tc_users.rb:26:in `test_roles'
        from /usr/lib/ruby/1.8/test/unit/testcase.rb:70:in `run'
        from /usr/lib/ruby/1.8/test/unit/testsuite.rb:32:in `run'
         ... 7 levels...
        from /usr/lib/ruby/1.8/test/unit/autorunner.rb:200:in `run'
        from /usr/lib/ruby/1.8/test/unit/autorunner.rb:13:in `run'
        from /usr/lib/ruby/1.8/test/unit.rb:285
        from test/tc_users.rb:25

It executes this sql:
SELECT COUNT(*) FROM ogrole WHERE user_oid = 1

Look at the where clause, it is user_oid and not user_owner_oid

This is the description of the table generated by og
mysql> desc ogrole;
+----------------+---------+------+-----+---------+----------------+
| Field                  | Type    | Null   | Key   | Default | Extra          |
+----------------+---------+------+-----+---------+----------------+
| permissions        | text    | YES   |        | NULL    |                |
| user_owner_oid | int(11) | YES  |         | NULL    |                |
| oid                     | int(11) |         | PRI  | NULL    |
auto_increment |
+----------------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

The mapping is correct but the query is not..

Is this a bug or i'm missing something?

I know that this problem can be solved jos changing the property
user_owner back to user, but what can i do when i have 2 has_many
relationships from User to Role for example..

class User
	....
	has_many :roles_he_like, Role
	has_many :roles_he_doesnt_like, Role
	....		
end

class Role
	belongs_to :user, User
	has_one :user_doesnt_like, User	
end

And make this test
def test_roles
    assert_equal 2, @user1.roles_he_like.size #has_many - belongs_to
relationship
    assert_equal 0, @user1.roles_he_doesnt_like.size #has_many -
has_one relationship
  end
#In mysql
desc ogrole;
+----------------------+---------+------+-----+---------+----------------+
| Field                          | Type    | Null    | Key  | Default
| Extra          |
+----------------------+---------+------+-----+---------+----------------+
| permissions               | text     | YES  |         | NULL    |   
            |
| user_oid                    | int(11) | YES  |        | NULL    |   
            |
| user_doesnt_like_oid | int(11) | YES  |        | NULL    |                |
| oid                             | int(11) |         | PRI | NULL   
| auto_increment |
+----------------------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

And the result of the test:
  1) Failure:
test_roles(TestUsuario) [test/tc_users.rb:27]:
<0> expected but was
<2>.

1 tests, 2 assertions, 1 failures, 0 errors

This is because it makes this sql query for @user1.roles_he_doesnt_like.size
SELECT COUNT(*) FROM ogrole WHERE user_oid = 1
and not
SELECT COUNT(*) FROM ogrole WHERE user_doesnt_like_oid = 1

Sorry for this long long long mail   ;->

Humber




More information about the Nitro-general mailing list